==Variables==
[[Variable (programming)|Variable]]s in standard JavaScript have no [[Type system|type]] attached,<!-- Wait,so variablesany dovalue have(each a type, but you don't'value'' declarehas it. Also there'sa type coercion. --> and any value) can be stored in any variable. Before ES6, variables were declared only with a <code>var</code> statement. Starting with [[ECMAScript#6th Edition - ECMAScript 2015|ES6]], the 6th version of the language finalised in 2015, variables can alsocould be declared with <code>var</code> for function scoped variables, and <code>let</code> or <code>const</code> which are for [[block scope|block level]] variables. Before TheES6, valuevariables could only be declared with a <code>var</code> statement. Values assigned to avariables declared with <code>const</code> cannot be changed, but its properties can. AnA variable's [[Identifier (computer languages)|identifier]] must start with a letter, underscore (<tt>_</tt>), or dollar sign (<tt>$</tt>);, while subsequent characters can also be digits (<tt>0-9</tt>). Because JavaScript is case sensitive, so the uppercase characters "A" through "Z" are different from the lowercase characters "a" through "z".
Starting with JavaScript 1.5, [[ISO 8859-1]] or [[Unicode]] letters (or <tt>\uXXXX</tt> Unicode escape sequences) can be used in identifiers.<ref>{{cite web | url=https://developer.mozilla.org/en/JavaScript/Guide/Values,_Variables,_and_Literals&revision=22#Variables | title=Values, Variables, and Literals - MDC | date=16 September 2010 | publisher=Mozilla Developer Network | access-date=1 February 2020 | archive-url=https://web.archive.org/web/20110629131728/https://developer.mozilla.org/en/JavaScript/Guide/Values%2C_Variables%2C_and_Literals%26revision%3D22#Variables | archive-date=29 June 2011 | url-status=dead }}</ref> In certain JavaScript implementations, the at sign (@) can be used in an identifier, but this is contrary to the specifications and not supported in newer implementations. {{citation needed}}
===Scoping and hoisting===
Variables declared with <code>var</code> are [[lexical scoping|lexically scoped]] at a [[function scope|function level]], while ones with <code>let</code> or <code>const</code> have a [[block scope|block level]] scope. Declarations are processed before any code is executed. This is referred to as ''{{visible anchor|hoisting}}'', and it is equivalent to variables being [[Forward declaration|forward declared]] at the top of the function or block, and is referred to as ''{{visible anchor|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><!-- Might not explain scoping very well -->
With <code>var</code>, the<code>let</code>, variable value isand <code>undefinedconst</code> untilstatements, itonly isthe initialized,declaration andis [[forwardhoisted; reference]]assignments isare not possiblehoisted. Thus a {{code|lang=javascript|code=var x = 1}} statement in the middle of the function is equivalent to a {{code|lang=javascript|code=var x}} declaration statement at the top of the function, and an {{code|lang=javascript|code=x = 1}} assignment statement at that point in the middle of the function. –This onlymeans theyou declarationcannot isaccess hoisted,values notbefore thethey assignment. Variablesare declared; with[[forward reference]] is not possible. With <code>letvar</code> ora variable's value is <code>constundefined</code> dountil notit setis theinitialized. valueVariables todeclared with <code>undefinedlet</code>, soor <code>const</code> cannot be accessed until it is initialized, so referencing the variable will cause an error.<!-- Some sources: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting. Referencing a let or const will not throw if there's a typeof. An exception to the typeof exception is "const x = x;", which you can try in the console. -->
Function statementsdeclarations, whose effect is towhich declare a variable ofand typeassign a function to it<code>!-- Function</code> andtechnically assignisn't actually a valuetype. toThey're itobjects which can be executed in a subroutine. -->, are similar to variable statements, but in addition to hoisting the declaration, they also hoist the assignment – as if the entire statement appeared at the top of the containing function – and thus forward reference is also possible: the ___location of a function statement within an enclosing function is irrelevant. This is different from a function expression being assigned to a variable in a <code>var</code>, <code>let</code>, or <code>const</code> statement.
So, for example,
Be sure to understand that
<syntaxhighlight lang="javascript">
var func = function() { .. } // willdeclaration NOT beis hoisted only
function func() { .. } // willdeclaration beand assignment are hoisted
</syntaxhighlight>
Block scoping can be produced by wrapping the entire block in a function and then executing it – this is known as the [[immediately-invoked function expression]] pattern – or by declaring the variable using the <code>let</code> keyword. <!-- Two totally slightly different things, wrapping cope in a block executes the whole code in a block, while let-or-const variables can be seen in the same block. So block-scope code, where code is executed, block-scope variables, where variables can be accessed. -->
===Declaration and assignment===
Variables declared outside anya functionscope are in [[global variable|global]]. If a variable is declared in a higher scope, it can be accessed by child functionsscopes.
When JavaScript tries to '''resolve''' an identifier, it looks in the local function scope. If this identifier is not found, it looks in the next outer function that declared the local onescope, and so on along the ''scope chain'' until it reaches the ''global scope'' where global variables reside. If it is still not found, JavaScript will raise a <code>ReferenceError</code> exception.
When '''assigning''' an identifier, JavaScript goes through exactly the same process to retrieve this identifier, except that if it is not found in the ''global scope'', it will create the "variable" asin athe propertyscope ofwhere theit ''globalwas object''created. <ref>ECMA-262 5e edition clarified this confusing behavior introducingwith the notion of ''Declarative Environment Record'' and ''Object Environment Record''. With this formalism, the ''global object'' is the ''Object Environment Record'' of the global ''Lexical Environment'' (the ''global scope'').</ref> As a consequence, a variable never declared will be global, if assigned. Declaring a variable (with the keyword <code>var</code>) in the ''global codescope'' (i.e. outside of any function body (or block in the case of let/const)), assigning a never declared identifier or adding a property to the ''global object'' (usually ''window'') will also create a new global variable.
Note that JavaScript's ''strict mode'' forbids the assignment of an undeclared variable, which avoids global namespace pollution. Also <code>const</code>!-- cannotRemoved, beunrelated declaredto withoutthe initializationfirst statement and sentence was already stated. Delete this comment if you edit this, this is just an explanation for my big edit. -->
=== Examples ===
Here are some examples of variable declarations and scope:
<!-- Maybe in this example, function f should also have a local shadowing variable name x2 -->
<syntaxhighlight lang="javascript">
var xx1 = 0; // A global variable, because it is not in any function
let x2 = 0; // Also global, this time because it is not in any block
function f() {
child();
return xx1 + x2; // We can use xx1 and x2 here, because itthey isare global
}
<syntaxhighlight lang="javascript">
for (let i = 0; i < 10; i++) console.log(i);
console.log(i); // throws a ReferenceError: i is not defined
</syntaxhighlight>
<syntaxhighlight lang="javascript">
for (const i = 0; i < 10; i++) console.log(i); // throws a TypeError: Assignment to constant variable
const pi; // throws a SyntaxError: Missing initializer in const declaration
|