Introduction
Many of us are already familiar with the scripting language JavaScript for its popularity. Dealing with such a loosely typed language is sometimes cumbersome and it is often more difficult to get out of irksome situations. Some people often criticize the language for being very forgiving. What adds fuel to the fire are our many techies who also criticize the language for the same reason. We are so busy accepting the misleading facts that we do not obey the concepts behind JavaScript.
This article is to throw light on how variables in JavaScript actually works. Trust me, if we understand the inner working and the concept behind it then we are a master and are less susceptible to fall into the situation where we say, damn I hate JavaScript. The target audience is the beginner but for the experienced, I hope this is a source of some revelation.
I will describe variables, variables inside functions, variables inside nested functions, and Scope Chains for variables. In short, the article will revolve around variables.
Using the code
A variable is a named location for storing a value.
Code
The preceding code is simple, we are declaring the two variables x and y and assigning a value to them.
Output
The necessity to use a var for declaring variables
Well, the answer is no but I personally use a var to declare variables as a good practice. The preceding code can also be written as in the following:
Code
Output
Although the output is the same, it doesn't make any difference even if you don't use var in the preceding case. But you will see shortly how just forgetting var plays a vital role. For the time being let's concentrate on the code, we wrote so far. In both of my examples I declared the two variables x and y. The only difference being in the first one we declared variables using the var keyword whereas in the second example I didn't use a var.
In both of the cases, the variables become the properties of the global object, in other words, you will be able to access x and y from any section of the code throughout but after obeying the scope resolution. Don't panic, we will get to scope resolution but for the time being, note the one point that x and y are declared in both of the examples and will become properties of the global object.
“A global object is an object that is used to represent the viewport or the browser screen where your page is rendered.”
So far so good but now we will see the difference when I use the same statements inside the function.
Code for Case 1: Declaring variables without using var.
Output
Code for Case 2: Declaring variables using the var keyword.
Output
What happened? In our second sample, it is throwing a reference error. Well, let's understand the reason for that. In the first case, after the function execution, the variables x and y become the properties of the global object but that was not the case when you declared the variable using the Case 2 code. In Case 2 x and y are limited to the function, not to x and y, and they are accessible within the function, not outside its boundary.
Wow, we have learned one important concept. Trust me, many developers do such kinds of things and then blame JavaScript. You just noticed what ignorance can cause.
Let's advance further upon what I just said. In the second case, x and y are accessible only inside the function.
Why
The answer is the Scope Chain. In simple words, a Scope Chain is basically a chain of objects or a list of objects JavaScript looks at for variable resolution. In the second case, x and y are defined for the function TestaAndy, not for the global object because we specifically used the var keyword. A function is also an object in JavaScript.
Thus in case 2 after function execution when we try to access x and y the scope chain is not available because we are outside the function. The scope chain available outside the function is just the global object; x and y are not properties of it so the Reference error is thrown but in Case 1 after function execution x and y becomes the properties of the global object so when the scope chain is referred to the x and y values are accessible.
Let's complicate the problem a little bit more.
I will be displaying the output at the end. Just understand the code first on the basis of learning we have until yet after reading the article.
- First, we have declared the two variables x and y. Note we haven't used var thus they will become properties of the global object after execution.
- We have a function TestxAndy. Inside the function, we have declared x, y, z, and simple variables. Notice x and y are also defined outside the function without using var and we declared x and y again but this is using the var keyword. We have already learned that these x and y will be treated as properties of TestxAndy, not of the global object after function execution. Note that we know properties are for objects but don't forget, in JavaScript functions are also objects so it is not wrong to say that x and y will become the properties of TestxAndy.
- z is again declared without using var thus it will become the property of the global object after function execution.
- simpleVariable is again a variable defined inside TestxAndy just like x and y but the only difference is its name is not clashing with any variable outside the function and we will restrict our learning to the fact that the simpleVariable will also become property of TestxAndy.
- Hmmm. The interesting things is that we have a nested function named NestedTestxAndy. Well, we are just displaying the values of x, y, and z via its code. Please note the execution of this function is dependent on TestxAndy because the call for this function invocation is made only via TestxAndy.
- Once we are done with our code we are invoking the function TestxAndy. Note that TestxAndy internally calls NestedTestxAndy and then we are displaying variable values.
Just a small request before jumping to the next figure that displays the output. Please note the output that you expect and then cross-check. If your output is the same as the next figure then you nailed it. If the output is not the same then Bravo, just appreciate yourself that you have made an effort and mistakes do happen. Trust me, I have also taken much time to understand this concept.
Output Explanation
On execution of TestxAndy;NestedTestxAndy is internally called. The scope chain associated with NestedTestxAndy has access to x and y of both of the objects, in other words, the global object as well as TestxAndy. Now, which value of x and which value of y will he prefer? The answer is the Scope Chain that starts with the most inner to the most outer. For NestedTestxAndy the most inner object is TestxAndy thus 100 and 200 will be displayed. z is a property of the global object and TestxAndy doesn't have any property with the name z. Don't get confused, we have declared z inside TestxAndy but since we didn't use var it becomes a property of the global object. Thus 300 will be displayed. The variable simpleVariable is a property of TestxAndy and its value will simply be displayed.
Well, the output after function execution is done, now what about our simple console.log statements where we are displaying the variable's values? The scope chain associated outside has just a global object in its chain, thus our solution is simple. If the variable is a property of the global object then the value will be displayed, otherwise, a Reference error is thrown. Therefore x will be 10, y will be 20, z will be 300, and accessing simpleVariable will throw a Reference Error because it is not the property of the global object.
Now pat yourself on the back, you have learned a concept. Enjoy and keep sharing your knowledge.