JS supports lexical scopes, that is, with few exceptions, a reference to a variable is bound to the scope that declares the variable most recently.
JS does not support block-level scopes, meaning that the scope of a variable definition is not the enclosing statement or block of code closest to it, but the function that contains them.
Not knowing this will create some subtle bugs.
Functon Iswinner (palyer,others) { var highest=0; for (Var i=0,n=others.length;i<n;i++) { var palyer=others[i]; if (player.score>highest) { highest=player.score; } } return player.score>highest;}
The For loop here declares a local variable player, but since the variable in JS is a function-level scope rather than a block-level scope, the internally declared player variable simply re-declares a variable that already exists within the scope (parameter player)
Each iteration of the loop overrides the same variable. The return statement therefore considers the player the last element of others, not the parameter player for this function.
A good way to understand the behavior of JS variable declaration is to think of the variable declaration as two procedures, one is the declaration process, and the other is the assignment process .
JS implicitly promotes the declaration part to the top of the enclosing function, while leaving the assignment in place . So the function above is equivalent.
Functon Iswinner (palyer,others) { var highest=0; var palyer; for (Var i=0,n=others.length;i<n;i++) { palyer=others[i]; if (player.score>highest) { highest=player.score; } } return player.score>highest;}
It is legal to declare the same variable multiple times in the same function. Variable declaration elevation can also cause confusion in variable re-declarations.
function Trimsections (header,body,footer) {for (var i=0,n=header.length;i<n;i++) { header[i]=header[i] . Trim (); } for (Var i=0,n=body.length;i<n;i++) { body[i]=body[i].trim (); } for (Var i=0,n=footer.length;i<n;i++) { Footer[i]=footer[i].trim ();} }
After the variable is promoted the equivalent
for (i=0,n=body.length;i<n;i++) { Body[i]=body[i].trim ();} for (i=0,n=footer.length;i<n;i++) { Footer[i]=footer[i].trim ();}
Because the re-declaration leads to distinct variable representations, some programmers prefer to avoid ambiguity by placing all Var declarations at the top of the function by effectively manually elevating variables.
It is important to understand the scope rules of JS, whether it is writing code or reading code .
An exceptional benefit of JS without block-level scope is its exception handling.
The Try...catch statement binds the caught exception to a variable that is scoped to the catch block only.
function test () { var x= "var", res=[]; Res.push (x); try{ Throw "Exception"; } catch (x) { x= "catch"; } Res.push (x); return res;} Test ();//["var", "var"]
Tips
- Variable declarations in code blocks are implicitly promoted to the top of the enclosing function
- Re-declaring a variable is treated as a single variable
- Consider manually raising the declarations of local variables to avoid confusion
[Effective JavaScript note] 12th: Understanding Variable Declaration elevation