Javascript Scope and Closure Details

  • 2021-11-29 22:52:28
  • OfStack

Directory 1, Scope 2, Scope Chain 3, Lexical Scope 5, Closure Application 6, Closure Defect 7, High Frequency Closure Interface Test

1. Scope

Simply put, scope refers to the area in a program where variables are defined, which determines the access rights of the currently executing code to variables

In ES5, 1 generally has only two scope types:

Global scope: Global scope is the outermost scope of the program, and 1 exists directly Function scope: Function scope is created only when the function is defined, and is included in the parent function scope or global scope

Having finished the concept, 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()      //  What will print out here? 

Analysis:

First, this code forms global scope and function scope Global scope has one variable a assigned to 100 Local variables b, a, c are defined in the scope of the test function There is variable promotion here, and the variable promotion var b; is carried out first in the function scope; var a; var c; When b is assigned, a has not been assigned at this time, so the value of a is undefined, and then a*2, so b is NaN Assign a 200 and c a/2 equals 100

So it will eventually print out NaN, 100

In ES6, a new block-level scope is added

Simply put, curly braces {...} The area within is the block-level scope, but Javascript Does not support block-level scope natively, and needs to use the ES6 Proposed let , const To create block-level scope


// ES5
if(true) {
  var name = ' Nan Jiu '
}
console.log(name)  //  Nan Jiu 

// ES6
if(true) {
  let age = 18
}
console.log(age)  //  Errors will be reported here 

2. Scope chain

When the executable code accesses a variable internally, it will first find whether there is a variable in the current scope, and then return immediately. If there is no variable, it will go to the parent scope to find it... 1 and find the global scope. We call this nesting mechanism of scope 作用域链

3. Lexical scope

词法作用域 Is a working model of scope, and lexical scope is JavaScript Lexical scope can also be called 静态作用域 .

The so-called lexical scope is determined by where you write variables and scopes when you write code, that is, lexical scope is a static scope, which is determined when you write code. The scope of a function depends on the location it declares, regardless of the location where it is actually called

MDN Definition of Closure:

A function and a reference to its surroundings (lexical environment) are bundled in 1 (or the function is surrounded by references), so that a combination is a closure ( closure )

In other words, closures allow you to access the scope of an inner function to its outer function. In JavaScript Whenever a function is created, closures are created at the same time as the function is created.

We can draw the following conclusions:

闭包 = 函数 + 外层作用域

Let's look at a piece of code first:


var name = ' Front-end Nanjiu '

function say() {
  console.log(name)
}
say()

Analysis: say Function can access the outer-scoped variable a, so isn't this a closure?

In the book "Javascript Authoritative Guide", there is such a sentence: Strictly speaking, so JavaScript All functions are closures

But this is only a theoretical closure, which is not quite the same as what we usually use. The above example is just a simple closure.

ECMAScript Definition of Closure:

Theoretically, all functions are closures. Because they are already stored in the upper context when they are created. Practically speaking, closures should satisfy two conditions: 1. Outer-scoped variables are referenced in the code; 2. Even if the context in which it was created has been destroyed, it still exists;

Let's look at the code in one more section of "JavaScript Authoritative Guide":


let scope = 'global scope'
function checkscope(){
  let scope = 'local scope'
  function f(){
    return scope
  }
  return f
}

let s = checkscope()   
s()   //  What returns here? 

Many students may think it is global scope But is this really the case? Let's take a look at its implementation process:

First, the global code is executed, the global execution context is created, and the global variables are defined scope And assign values Affirm checkscope Function, and create the execution context of the function, and create local variables scope And assign values Declare the f function and create the execution context of the function Execute checkscope Function, which returns an f function assigned to the variable s Executing the s function is equivalent to executing the f function. Returned here scope Yes local scope . As for why it is local scope We talked about morphology above

Basic rules of action: JavaScript Functions are executed using the scope in which they are defined. In the scope that defines the f function, the variable scope The value of is local scope

5. Application of Closure

The application of closures is mostly used in the context of maintaining internal variables

6. Closure defects

Because the existence of closures may cause variables to stay in memory, improper use will cause memory leakage Memory leaks may cause applications to jam or crash

7. High-frequency closure questions


var arr = []
for(var i=0;i<3;i++){
    arr[i] = function(){
        console.log(i)
    } 
}
arr[0]()  // 3
arr[1]()  // 3
arr[2]()  // 3
//  When executing here, i Has become 3

//  Using closures to resolve 
var 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]()  // 2

Related articles: