❝
I’m sure most of you have heard of closures, but few of you will be able to explain in detail what a closure is. To be honest, closures are very common in development, and closures are also very common in front-end interviews. Before we learn about closures, we will first look at scopes and scope chains, because this is the key to closures.
❞
scope
❝
Simply put, a scope is the area of a program where variables are defined, and it determines how much access the currently executing code has to the variables
❞
In ES5, there are generally only two scope types:
- Global scope: As the outermost scope of the program, the global scope always exists
- Function scope: A function scope is created only when the function is defined, either in the parent function scope or in the global scope
With that out of the way, let’s look at the following code:
Var a = 100 function test(){var b = a * 2 var a = 200 var c = a/2 console.log(b) console.log(c)} test(){var b = a * 2 var a = 200 var c = a/2 console.log(c)} test()Copy the code
❝
Resolution:
1. First, this code forms a global scope and a function scope
2. The global scope has a variable a with a value of 100
3. Local variables B, A,c are defined in the test function scope
4. There is variable promotion in the function scope, var b is promoted first; var a; var c;
A *2 = NaN; a*2 = NaN; b = NaN
6. Assign a to 200 and C to a/2 = 100
“So it will eventually print NaN, 100.”
❞
In ES6, there is a new ** “block-level scope” **
❝
Simply put, curly braces {… } are block-level scopes, but Javascript does not support block-level scopes natively. You need to create block-level scopes with the help of ES6’s let, const
❞
// ES6 if(true) {let age = 18} console.log(age) // An error will be reportedCopy the code
The scope chain
❝
When the executable code accesses a variable internally, it looks for the variable in the current scope. If it does, it returns it immediately. If it does not, it looks for the variable in the parent scope. Go all the way to the global scope. We refer to this nesting mechanism of scopes as scope chains
❞
Lexical scope
Lexical scope is a working model of scope. Lexical scope is a type of scope used in JavaScript. Lexical scope can also be called static scope.
❝
The so-called lexical scope is determined by where you write variables and scopes when you write code, that is, the lexical scope is static, determined when you write code. “The scope of a function depends on where it is declared, not where it is actually called.”
❞
MDN definition of closure:
A combination of a function that is bound (or surrounded by) references to its surrounding lexical context is a closure.
That is, closures allow you to access the scope of an outer function within an inner function. In “JavaScript,” whenever a function is created, the closure is created at the same time the function is created.
“We can conclude:”
❝
Closure = function + outer scope
❞
Let’s start with this code:
Var name = 'console.log' function say() {console.log(name)} say()Copy the code
The say function can access variable A in the outer scope, creating a closure.
In the definitive guide to Javascript, there is a quote: “Strictly speaking, all Javascript functions are closures.”
But this is just a theoretical closure, not quite the one we’re used to. The above example is just a simple closure.
ECMAScript definition of a closure:
- In theory: all functions are closures. Because they are created with the data stored in the upper context.
- As a practical matter, closures should satisfy two conditions:
- 1. References variables in the outer scope in the code;
- 2. It exists even if the context in which it was created has been destroyed;
Let’s take a look at some code from the Definitive guide to JavaScript:
let scope = 'global scope' function checkscope(){ let scope = 'local scope' function f(){ return scope } return f } let S = checkScope () s()Copy the code
Many students may think it is global Scope, but is it really so? Let’s take a look at its implementation process:
❝
1. Execute the global code first, create the global execution context, define the global variable scope and assign the value
2. Declare the checkScope function, create the execution context of the function, create the local variable scope and assign the value
3. Declare the f function and create the execution context of the function
4. Execute the checkScope function, which returns a function f assigned to variable s
5. Performing the S function is equivalent to performing the F function. The scope returned here is local Scope. As for why local scope, we covered the basic rules of lexical manipulation above: JavaScript functions are executed using the scope that defines them. In the scope where f is defined, the value of the variable scope is local scope
❞
Application of closures
❝
Closures are mostly used in the context of maintaining internal variables
❞
Defects in closures
- Since the presence of closures can cause variables to reside in memory, improper use can cause memory leaks
- A memory leak can cause an application to stall or crash
High frequency closure interview questions
var arr = [] for(var i=0; i<3; I++) {arr [I] = function () {the console. The log (I)}} arr [0] () / / 3 arr [1] () / / 3 arr [2] () / / 3 / / here at the time of execution has been changed to 3 / I solve var/using closures arr = [] for(var i=0; i<3; i++){ arr[i] = (function(i){ return function(){ console.log(i) } })(i) } arr[0]() // 0 arr[1]() // 1 arr[2]() // 2Copy the code