For the scope of variables, languages such as C, Java adopt the "block scope" method. In contrast, JavaScript adopts the "function scope" method - the scope of the variable is determined only by the function in which it is located and has nothing to do with logical blocks such as if and for. For example, the following example shows the behaviors in JavaScript that are different from languages such as C and Java:
The code copy is as follows:
function(){
var s = 42;//s is visible throughout function
if (s > 3) {
var x = "test";//x is visible throughout function
for(var i=0; i<10; i++){
console.log(i);
}
console.log(i);//i is visible throughout function
}
console.log(i);
console.log(x);
}
In "block scope" languages such as C and Java, after logical blocks such as if statements and for statements are completed, variables defined inside these logical blocks will be destroyed. JavaScript is different. As long as a variable is defined within a function, all codes in the entire function can access the variable, even if the codes are before the variable definition:
The code copy is as follows:
function(){
console.log(a);//undefined
var a = "test";
console.log(a);//test
}
In the above example, if a is never defined in function, console.log(a) will throw a ReferenceError. When a is defined in function, even if this definition is after the a variable calling statement, the call to a is a legal operation (if the definition of a variable occurs after the call statement, the value of a variable in the call statement is undefined). In fact, all variables defined with the var keyword in the function will be raised to the beginning of the function (the assignment operation remains on the line defined by the var), which is called hoisting in JavaScript. For example, the above code is equivalent to:
The code copy is as follows:
function(){
var a;
console.log(a);//undefined
a = "test";
console.log(a);//test
}
Scope chain of variables
Contacting the storage of variables in JavaScript can provide a good understanding of "function scope" and hoisting in JS. Since variables are stored on global objects or function call objects, when defining a variable in a function, no matter where the variable is defined in the function call, a property with the same name as this variable will inevitably appear in the function call object used by this function call. This allows the variable to be accessed anywhere in the function.
When it comes to function calls, there is another more interesting concept in JavaScript: the scope chain of variables - Since variables are stored on global objects or function call objects, when accessing variables, you can get values from multiple objects. The following code is an example:
The code copy is as follows:
var x = "test";
function(){
//level-1 function
var x = "temp";
function(){
//level-2 function
var x = "real";
//try to access x here. x will be "real".
}
}
Inside the level-2 function in the above code, when trying to access the x variable, the program can search for the corresponding attribute values from 3 objects: the function call object used to call the level 2 function, the function call object used to call the level 1 function, and the global object - According to the nested relationship defined by the function, JavaScript will generate an object chain composed of the global object and the function call object. When accessing variables, the program will start searching from the object closest to the access statement. If no search is found, it will continue to search in the object at the previous level in the object chain until the global object.
Since this object chain is related to the scope of the variable, it is also called the "scope chain".
If you need to temporarily change the scope chain and insert an object into the front end of the scope chain (as the function object that is accessed first), you can use the with statement:
The code copy is as follows:
with(o){
//code use properties of object o.
}
However, in JavaScript strict mode, with statements are disabled; even in non-strict mode, with statements are not recommended.