What is the scope of variables in javascript? Do they have the same scope inside as opposed to outside a function? Or does it even matter? Also, where are the variables stored if they are defined globally?
Join them; it only takes a minute:
|
|
I think about the best I can do is give you a bunch of examples to study. Javascript programmers are practically ranked by how well they understand scope. It can at times be quite counter-intuitive.
|
|||||||||||||||||||||
|
|
Javascript uses scope chains to establish the scope for a given function. There is typically one global scope, and each function defined has its own nested scope. Any function defined within another function has a local scope which is linked to the outer function. It's always the position in the source that defines the scope. An element in the scope chain is basically a Map with a pointer to its parent scope. When resolving a variable, javascript starts at the innermost scope and searches outwards. |
|||||
|
|
Variables declared globally have a global scope. Variables declared within a function are scoped to that function, and shadow global variables of the same name. (I'm sure there are many subtleties that real JavaScript programmers will be able to point out in other answers. In particular I came across this page about what exactly |
|||||||||
|
|
Here's an example:
You'll want to investigate closures, and how to use them to make private members. |
|||
|
|
|
The key, as I understand it, is that Javascript has function level scoping vs the more common C block scoping. |
|||
|
|
Old school JavaScriptTraditionally, JavaScript really only has two types of scope :
I will not elaborate on this, since there are already many other answers explaining the difference. Modern JavaScriptThe most recent JavaScript specs now also allow a third scope :
How do I create block scope variables?Traditionally, you create your variables like this :
Block scope variables are created like this :
So what is the difference between functional scope and block scope?To understand the difference between functional scope and block scope, consider the following code :
Here, we can see that our variable Is it safe to use block scope variables today?Whether or not it is safe to use today, depends on your environment :
How to keep track of browser supportFor an up-to-date overview of which browsers support the |
|||||
|
|
In "Javascript 1.7" (Mozilla's extension to Javascript) one can also declare block-scope variables with
|
|||||||||||||||||||||
|
|
1) There is a global scope, a function scope, and the with and catch scopes. There is no 'block' level scope in general for variable's -- the with and the catch statements add names to their blocks. 2) Scopes are nested by functions all the way to the global scope. 3) Properties are resolved by going through the prototype chain. The with statement brings object property names into the lexical scope defined by the with block. EDIT: ECMAAScript 6 (Harmony) is spec'ed to support let, and I know chrome allows a 'harmony' flag, so perhaps it does support it.. Let would be a support for block level scoping, but you have to use the keyword to make it happen. EDIT: Based on Benjamin's pointing out of the with and catch statements in the comments, I've edited the post, and added more. Both the with and the catch statements introduce variables into their respective blocks, and that is a block scope. These variables are aliased to the properties of the objects passed into them.
EDIT: Clarifying example: test1 is scoped to the with block, but is aliased to a.test1. 'Var test1' creates a new variable test1 in the upper lexical context (function, or global), unless it is a property of a -- which it is. Yikes! Be careful using 'with' -- just like var is a noop if the variable is already defined in the function, it is also a noop with respect to names imported from the object! A little heads up on the name already being defined would make this much safer. I personally will never use with because of this. |
|||||||||||||||||||||
|
|
The idea of scoping in JavaScript when originally designed by Brendan Eich came from the HyperCard scripting language HyperTalk. In this language, the displays were done similar to a stack of index cards. There was a master card referred to as the background. It was transparent and can be seen as the bottom card. Any content on this base card was shared with cards placed on top of it. Each card placed on top had its own content which took precedence over the previous card, but still had access to the prior cards if desired. This is exactly how the JavaScript scoping system is designed. It just has different names. The cards in JavaScript are known as Execution ContextsECMA. Each one of these contexts contains three main parts. A variable environment, a lexical environment, and a this binding. Going back to the cards reference, the lexical environment contains all of the content from prior cards lower in the stack. The current context is at the top of the stack and any content declared there will be stored in the variable environment. The variable environment will take precedence in the case of naming collisions. The this binding will point to the containing object. Sometimes scopes or execution contexts change without the containing object changing, such as in a declared function where the containing object may be These execution contexts are created any time control is transferred. Control is transferred when code begins to execute, and this is primarily done from function execution. So that is the technical explanation. In practice, it is important to remember that in JavaScript
Applying this to one of the previous examples (5. "Closure") on this page, it is possible to follow the stack of execution contexts. In this example there are three contexts in the stack. They are defined by the outer context, the context in the immediately invoked function called by var six, and the context in the returned function inside of var six's immediately invoked function. i) The outer context. It has a variable environment of a = 1 |
|||
|
|
|
I found that many people new to JavaScript have trouble understanding that inheritance is available by default in the language and that function scope is the only scope, so far. I provided an extension to a beautifier I wrote at the end of last year called JSPretty. The feature colors function scope in the code and always associates a color to all variables declared in that scope. Closure is visually demonstrated when a variable with a color from one scope is used in a different scope. Try the feature at: See a demo at: View the code at:
Currently the feature offers support for a depth of 16 nested functions, but currently does not color global variables. |
|||||
|
|
JavaScript have only two type of scope :
Whenever a function is called, a variable scope object is created (and included in scope chain) which is followed by variables in JavaScript.
Scope chain -->
Now when a variable |
|||||
|
|
run the code. hope this will give an idea about scoping
|
|||
|
|
Global Scope :Global variables are exactly like global stars (Jackie Chan, Nelson Mandela). You can access them (get or set the value), from any part of your application. Global functions are like global events (New Year, Christmas). You can execute (call) them from any part of your application.
Local Scope :If you are in the USA, you may know Kim Kardashian, infamous celebrity ( she somehow manages to make the tabloids). But people outside of the USA will not recognize her. She is a local star, bound to her territory. Local variables are like local stars. You can only access them (get or set the value) inside the scope. A local function is like local events - you can execute only (celebrate) inside that scope. If you want to access them from outside of the scope, you will get a reference error
|
||||
|
|
|
There are only function scopes in JS. Not block scopes! You can see what is hoisting too.
|
||||
|
There are ALMOST only two types of JavaScript scopes:
So, any blocks other than functions do not create a new scope. That explains why for-loops overwrite outer scoped variables:
Using functions instead:
In the first example, there was no block scope, so the initially declared variables were overwritten. In the second example, there was a new scope due to the function, so the initially declared variables were SHADOWED, and not overwritten. That's almost all you need to know in terms of JavaScript scoping, except:
So you can see JavaScript scoping is actually extremely simple, albeit not always intuitive. A few things to be aware of:
So this code:
is equivalent to:
This may seem counter intuitive, but it makes sense from the perspective of a imperative language designer. |
|||
|
|
|
Just to add to the other answers, scope is a look-up list of all the declared identifiers (variables), and enforces a strict set of rules as to how these are accessible to currently executing code. This look-up may be for the purposes of assigning to the variable, which is an LHS (lefthand-side) reference, or it may be for the purposes of retrieving its value, which is an RHS (righthand-side) reference. These look-ups are what the JavaScript engine is doing internally when it's compiling and executing the code. So from this perspective, I think that a picture would help that I found in the Scopes and Closures ebook by Kyle Simpson: Quoting from his ebook:
One thing of note that is worth mentioning, "Scope look-up stops once it finds the first match". This idea of "scope levels" explains why "this" can be changed with a newly created scope, if it's being looked up in a nested function. Here is a link that goes into all these details, Everything you wanted to know about javascript scope |
|||
|
|
|
Try this curious example. In the example below if a were a numeric initialized at 0, you'd see 0 and then 1. Except a is an object and javascript will pass f1 a pointer of a rather than a copy of it. The result is that you get the same alert both times.
|
|||
|
|
|
Global: variable declared outside of a function Local: variable declared inside a function, and can only be called in that scope |
|||||
|
|
There are two types of scopes in JavaScript.
|
||||
|
|
protected by Mr. Alien Mar 3 '14 at 19:06
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?


