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

Follow the official account for more selected articles ~