Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Scope (computer science)
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
=== JavaScript === [[JavaScript]] has simple ''scope rules'',<ref>"[http://www.coolcoder.in/2014/03/everything-you-need-to-know-about.html Everything you need to know about Javascript variable scope]", [http://www.coolcoder.in/p/about-us.html Saurab Parakh], ''[http://www.coolcoder.in/ Coding is Cool],'' 2010-02-08</ref> but variable initialization and name resolution rules can cause problems, and the widespread use of closures for callbacks means the lexical context of a function when defined (which is used for name resolution) can be very different from the lexical context when it is called (which is irrelevant for name resolution). JavaScript objects have name resolution for properties, but this is a separate topic. JavaScript has lexical scope <ref>{{cite web|url=https://es5.github.io/#x10.2|title=Annotated ES5|website=es5.github.io|access-date=19 March 2018}}</ref> nested at the function level, with the global context being the outermost context. This scope is used for both variables and for functions (meaning function declarations, as opposed to variables of [[function type]]).<ref>{{cite web|url=https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope|title=Functions|website=MDN Web Docs|access-date=19 March 2018}}</ref> Block scope with the <code>let</code> and <code>[[const (computer programming)|const]]</code> keywords is standard since [[ECMAScript]] 6. Block scope can be produced by wrapping the entire block in a function and then executing it; this is known as the [[immediately-invoked function expression]] (IIFE) pattern. While JavaScript scope is simple—lexical, function-level—the associated initialization and name resolution rules are a cause of confusion. Firstly, assignment to a name not in scope defaults to creating a new global variable, not a local one. Secondly, to create a new local variable one must use the <code>var</code> keyword; the variable is then created at the top of the function, with value <code>undefined</code> and the variable is assigned its value when the assignment expression is reached: :A variable with an ''Initialiser'' is assigned the value of its ''AssignmentExpression'' when the ''VariableStatement'' is executed, not when the variable is created.<ref>"[https://es5.github.io/#x12.2 12.2 Variable Statement]", Annotated ECMAScript 5.1, Last updated: 2012-05-28</ref> This is known as ''[[variable hoisting]]''<ref>"[http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html JavaScript Scoping and Hoisting]", [http://www.adequatelygood.com/about.html Ben Cherry], ''[http://www.adequatelygood.com/ Adequately Good],'' 2010-02-08</ref>—the declaration, but not the initialization, is hoisted to the top of the function. Thirdly, accessing variables before initialization yields <code>undefined</code>, rather than a syntax error. Fourthly, for function declarations, the declaration and the initialization are both hoisted to the top of the function, unlike for variable initialization. For example, the following code produces a dialog with output <samp>undefined</samp>, as the local variable declaration is hoisted, shadowing the global variable, but the initialization is not, so the variable is undefined when used: <syntaxhighlight lang="javascript"> a = 1; function f() { alert(a); var a = 2; } f(); </syntaxhighlight> Further, as functions are first-class objects in JavaScript and are frequently assigned as callbacks or returned from functions, when a function is executed, the name resolution depends on where it was originally defined (the lexical context of the definition), not the lexical context or execution context where it is called. The nested scopes of a particular function (from most global to most local) in JavaScript, particularly of a closure, used as a callback, are sometimes referred to as the '''scope chain''', by analogy with the prototype chain of an object. [[Closure (computer science)|Closures]] can be produced in JavaScript by using nested functions, as functions are first-class objects.<ref>[http://jibbering.com/faq/notes/closures/ Javascript Closures], Richard Cornford. March 2004</ref> Returning a nested function from an enclosing function includes the local variables of the enclosing function as the (non-local) lexical context of the returned function, yielding a closure. For example: <syntaxhighlight lang="javascript"> function newCounter() { // return a counter that is incremented on call (starting at 0) // and which returns its new value var a = 0; var b = function() { a++; return a; }; return b; } c = newCounter(); alert(c() + ' ' + c()); // outputs "1 2" </syntaxhighlight> Closures are frequently used in JavaScript, due to being used for callbacks. Indeed, any hooking of a function in the local context as a callback or returning it from a function creates a closure if there are any unbound variables in the function body (with the context of the closure based on the nested scopes of the current lexical context, or "scope chain"); this may be accidental. When creating a callback based on parameters, the parameters must be stored in a closure, otherwise it will accidentally create a closure that refers to the variables in the enclosing context, which may change.<ref> "[http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/ Explaining JavaScript Scope And Closures]", Robert Nyman, October 9, 2008</ref> Name resolution of properties of JavaScript objects is based on inheritance in the prototype tree—a path to the root in the tree is called a ''prototype chain''—and is separate from name resolution of variables and functions.
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)