Valid JavaScript Item 12 understand Variable Hoisting and variablehoisting
This series serves as the Reading Notes for objective JavaScript.
No Block Scoping exists in JavaScript, and only Function Scoping exists.
Therefore, if a variable is defined in a Block, the variable is defined in the Function of the Block, for example:
function isWinner(player, others) {var highest = 0;for (var i = 0, n = others.length; i < n; i++) {<span style="color:#ff0000;">var player = others[i];</span>if (player.score > highest) {highest = player.score;}}return player.score > highest;}
In the above Code, a Variable player is declared in the for loop. This Variable is declared as follows due to Variable Hoisting:
function isWinner(player, others) {<span style="color:#ff0000;">var player;</span>var highest = 0;for (var i = 0, n = others.length; i < n; i++) {<span style="color:#ff0000;">player = others[i];</span>if (player.score > highest) {highest = player.score;}}return player.score > highest;}
Therefore, the player parameter passed into the function is overwritten. The program cannot run as expected.
In JavaScript, the declaration of variables actually contains two parts:
- Statement itself
- Assignment
JavaScript uses Variable Hoisting to place the first part, that is, the declared part, in the header of the function containing the Variable.
In the following example:
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();}}
Because of VariableHoisting, both I and n are placed at the beginning of the function. In fact, only two variables are declared. In the for loop, they are assigned a value, the actual behavior is as follows:
function trimSections(header, body, footer) {<span style="color:#ff0000;">var i, n;</span>for (i = 0, n = header.length; i < n; i++) {header[i] = header[i].trim();}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 of the existence of VariableHoisting, some programmers prefer to define variables at the beginning of the function, which is equivalent to completing a manual Hoisting. The purpose is to avoid ambiguity and make the code clearer.
However, in a special case, try... In a catch statement, parameters in the catch block are bound to the block:
function test() {var x = "var", result = [];result.push(x);try {throw "exception";} catch (x) {<span style="color:#ff0000;">x = "catch";</span>}result.push(x);return result;}test(); // ["var", "var"]
Important:
- Variables declared in the Block are implicitly Hoisted to the beginning of the function containing them. (Except the catch block mentioned above)
- In a function, a variable is declared multiple times and only one variable is declared.
- To avoid ambiguity, consider declaring variables at the beginning of the function.