Since ES6 has block-level scopes, we’ll base it on ES5. This article combines previous articles in the series to discuss issues related to scopes and scope chains.
1. Scope
A scope in JavaScript (ES5) is a function scope. Compare this with C/C++/ Java and ES6 block-level scopes, which include scopes in braces after if criteria.
Block-level scopes in ES6
// ES6 lets define variables that are block-level scoped and cannot be accessed outside curly braces
for( let i = 0; i < 5; i++ ){
console.log(i); // 循环输出 0,1,2,3,4
}
console.log(i); // Uncaught ReferenceError: I is not defined The variable I cannot be accessed outside curly braces
Copy the code
There is no block-level scope in ES5, and variable I leaks out
// ES6 lets define variables that are block-level scoped and cannot be accessed outside curly braces
for( var i = 0; i < 5; i++ ){
console.log(i); // 循环输出 0,1,2,3,4
}
console.log(i); // Outputs 5
Copy the code
ES5 has two scopes: Global Scope and Local Scpoe.
1. Global Scope
The global scope is accessible from anywhere. It includes three cases:
- In the context of global execution, variables defined with var:
var global = "global";
function fn(){
console.log(global); // "global"
}
fn();
Copy the code
- A variable declared in a function body without the var keyword
function fn(){
global = "global"; // the fn function is not called. Internal variables declared without var are global variables
}
console.log(global); // "global"
Copy the code
- Define properties in the Window object
function fn(){
console.log(global); // "global"
}
window.global = "global";
fn();
Copy the code
2. Local scope (Local Scpoe)
Also known as function scope, is the definition of variables and functions that are accessible only within a function.
function fn(){
var str = "local";
}
console.log(str); // str is not defined
Copy the code
function fn1(){
var str = "local";
}
function fn2(){
console.log(str); // str is not defined
}
fn2()
Copy the code
function fn1(){
function fn2(){
var str = "local";
}
console.log(str); // str is not defined
}
fn1()
Copy the code
The variable STR is not accessible in any of the above cases, and STR is not accessible outside the scope of the function.
Scope Chain
As mentioned in the previous article on variable objects and active objects, when a function is called, it creates an execution context. This execution context has a creation phase and an execution phase. Variable objects are generated during the creation phase and become live objects during the execution phase. Now we discuss the creation of scope chains.
When calling a function, the code executes until it accesses a variable in the function body. The interpreter first looks for the variable in the current scope and takes its value if it finds it, instead of looking up one level in the scope. If the variable is not found in the current scope, it is searched in the upper scope, and the upper scope is not searched in the upper scope until it is found.
In JS, a Function is special. It is an instance of Function and can be used as an object. It has an internal programmable access property, and a Function has an internal non-directly accessible property [[scope]]. [[scope]] contains the set of objects in scope at the time the function was created. This set is called the scope chain of the function. It determines which objects can be accessed by functions.
function fn0(){
var a = 10;
function fn1(){
var b = 20;
function fn2(){
console.log( a + b ); / / 30
}
fn2();
}
fn1();
}
fn0();
Copy the code
[[Scope]]; fn0; fn1 Closure 1; fn0; fn1 Closure 1; fn0; fn1 Closure 1;
The diagram is as follows
- The Chrome V8 engine describes closures as outer functions, unlike some reference books that define inner functions as closures. The next article in this series will explain closures. ↩