Although the ‘with’ statement creates a block-level scope effect, and recent implementations of the “let” statement have the same effect, these are fodder for another conversation. I’m not a big fan of the “with” statement, and at the time of this writing, you can’t be 100% sure that the “let” statement is fully supported by the user’s browser. The end result of this is the fact that there is no block-level scope in JavaScript. Scope is created by functions.

Example # 1

Here is the jsFiddle.net link for Example # 1 : http://jsfiddle.net/2ZkkR/

In Example # 1, we set the global variable “month” equal to “july”. But inside of the function “foo()”, we also create a variable named “month”, and give it a value of “august”. The second statement in foo() is a call to the console, telling it to output the value of the variable “month”.

So, why is it that in the global scope, “console.log(month)” outputs “july”, but executing “foo()” outputs “august” ?

The reason is that inside of the function “foo()”, we used the “var” keyword to create the variable “month”. When you use the “var” keyword, the variable you create becomes local to the function that you create it in. So, inside of “foo()”, the variable “month” is local, and equal to “july”. As a result, on the very next line, the statement: “console.log(month)” outputs “july”. Inside of “foo()”, we have no knowledge of the global variable “month”, because in the scope chain, the variable “month” is found locally, so the search for “month” ends within the local scope of “foo()”.

Example # 2

Here is the jsFiddle.net link for Example # 2 : http://jsfiddle.net/6TBEM/

In Example # 2, we have added a function named “bar()”. Bar does not have a local variable named “month”. So, when “bar()” executes, the statement “console.log(month)” kicks off a search for the variable “month”. In the scope chain, there is no local variable named “month”, so the JavaScript engine looks to the next level of the scope chain, which happens to be the global scope. In the global scope, there is a variable named “month”, so the value of that variable is returned, and it is “july”.

So, “foo()” outputs: “august” and “bar()” outputs: “july”, because, although they both look for a variable named “month”, they find completely different values; in their respective scope chains, the value of a variable named “month” differs.

Example # 3

Here is the jsFiddle.net link for Example # 3 : http://jsfiddle.net/ZaXxk/

In Example # 3, notice a new statement in the “foo()” function: “window.season”.

In this statement, we are creating a global variable named “season”. Although we are within the context of the “foo()” function, we can reference the global scope by mutating the “window” object. “window” is essentially the global object. Creating a global variable while inside of the local scope of “foo()” is easily done by adding a property to the “window” object; in our case we name it “season” and give it a value of “summer”.

So once again, although we are in the local scope of “foo()”, we have just created a global variable named “season” and given it the value of “summer”, by adding a new property to the “window” object (e.g., window.season = ‘summer’).

Example # 4

Here is the jsFiddle.net link for Example # 4 : http://jsfiddle.net/XYu4x/

In Example # 4, we create another global variable while within the local scope of “foo()”, named “weather”. This approach is different because when we say: weather = “hot”, the absence of the “var” keyword automatically makes the variable global. This is important to remember and make note of: If you omit the “var” keyword when creating a variable, no matter where you do it, that variable becomes global.

In general, this is something that you want to avoid, as it can lead to code that is hard to understand and even harder to maintain. But for the purpose of this discussion, it illustrates an important behavior in JavaScript: omitting the “var” keyword when creating a variable makes that variable global, no matter where you do it. I’m repeating this because it is an important detail to remember.

Example # 5

Here is the jsFiddle.net link for Example # 5 : http://jsfiddle.net/NTjYe/

In Example # 5, we yet again create a new global variable from within the local scope of “foo()”. This variable is named “activity”. We demonstrate yet another way in which you can do this by saying: this.activity = ‘swimming’. This introduces another concept: the meaning of “this” inside a function (no pun intended).

Inside a function, the “this” keyword refers to the context in which the function is executed. In our example, “foo()” is executed in the context of the global object, so “this” referes to the global object, which means that “this.activity” adds a property to the global object named “activity”.

Make note: While “foo()” has it’s own “local” scope, the keyword “this” refers to the context in which “foo()” is executed. This is another important detail to remember. It will come up a lot when writing more advanced JavaScript.

Another (very) important note:  An “implied global” is what occurs when you omit the “var” keyword when declaring a variable. There is a subtle, yet important difference between that and a variable created using the “var” keyword in the global scope: an implied global is actually not a variable; it is a property of the “window” object. For the most part, it behaves very much like a global variable, but there are differences: for example, you cannot delete a global variable, but you can delete a property of the window object. This is a topic worth looking into when you have time, and at minmum, good to be aware of.

Summary

At first, the concept of scope in JavaScript can be a challenge to fully understand. But it is very much worth the effort. Once you understand scope, the JavaScript language becomes a sharp knife that can be used to sculpt elegant and expressive code. This tutorial discussed only the most basic concept of scope in JavaScript. I highly recommend exploring it in-depth.

Helpful Links for Scope in JavaScript

https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope/

http://coding.smashingmagazine.com/2009/08/01/what-you-need-to-know-about-javascript-scope/

http://oranlooney.com/function-scope-javascript/

2 Comments

Comments are closed.