5.4.4. Scope and Closures¶
5.4.4.1. Scope and scope chains¶
5.4.4.1.1. Scope¶
Simply put, the scope is the accessible scope of variables and functions, that is, the scope controls the visibility and life cycle of variables and functions. The scope of JavaScript is formed by functions, which means that the variables of a function cannot be accessed outside the function.
Scope can be divided into global scope, local scope and block-level scope. The global scope mainly has the following three situations:
Variables defined outside a function have global scope
Variables with undefined direct assignments are automatically declared to have global scope
The properties of the window object have global effects
The local scope is generally only accessible within a fixed code fragment, the most common being inside a function, so this scope is also called a function scope.
5.4.4.1.2. Scope leak¶
In the ES5 standard, there are only global scope and local scope, no block-level scope, which may cause the problem of variable leakage. E.g:
var i = 1;
function f() {
console.log(i)
if (true) {
var i = 2;
}
}
f(); // undefined
5.4.4.1.3. Scope Hoisting(var Hoisting)¶
In JavaScript, declaring a variable using var anywhere within a function or global is equivalent to declaring it at the very top inside of it. This behavior is called Hoisting. For example, the following code is equivalent to the second code:
function foo() {
console.log(x); // => undefined
var x = 1;
console.log(x); // => 1
}
foo();
function foo() {
var x;
console.log(x); // => undefined
x = 1;
console.log(x); // => 1
}
foo();
5.4.4.1.4. Scope chain¶
When a function is executed, it always looks for local variables from inside the function. If the corresponding variable cannot be found, it will look to the upper-level scope of the created function until the global scope is found. This process is called a scope chain. .
5.4.4.2. Closures¶
A function together with a reference to its state, the lexical environment, constitutes a closure. That is, closures allow you to access the outer function scope from the inner function. In JavaScript, functions generate closures each time they are created.
In JavaScript, there is no native support for private methods, i.e. an element/method can only be called by other methods in the same class. Closures are a solution that can be used to mock private methods. In addition, closures also provide the ability to manage the global namespace, preventing non-core methods or properties from polluting the public interface part of the code. Here is a simple example:
var Counter = (function() {
var privateCounter = 0;
function changeBy(val) {
privateCounter += val;
}
return {
increment: function() {
changeBy(1);
},
decrement: function() {
changeBy(-1);
},
value: function() {
return privateCounter;
}
}
})();
console.log(Counter.value()); /* logs 0 */
Counter.increment();
Counter.increment();
console.log(Counter.value()); /* logs 2 */
Counter.decrement();
console.log(Counter.value()); /* logs 1 */
5.4.4.3. Global Objects¶
A global object is a special object whose scope is global.
The global object available on all platforms is the globalThis
same as this value in the global scope. In addition, there are self
and window
global objects in Web Workers, and global
global objects in Node.js.