current position:Home>Fried cold rice series 4: scope and closure in JavaScript

Fried cold rice series 4: scope and closure in JavaScript

2022-04-29 18:54:29MaybeIsAdog

Form writing habits together ! This is my participation 「 Nuggets day new plan · 4 Yuegengwen challenge 」 Of the 6 God , Click to see the event details .

Preface

Last one Fried cold rice series 3: You must prepare for the interview 、 Prototype 、 Knowledge of prototype chain and inheritance ! It introduces Javascript The second mountain in , And the first mountain has been in the fried cold rice series 2 Described in the , namely Fried cold rice series 2: Take a look at the... In the face-to-face test Javascript Event cycle mechanism !. thus ,Javascript Two of the three mountains have been introduced , Let's finish it this time , Next, let's introduce the third mountain : Scope and closure .

background

This time there is no background , The background is also because it is a series with the previous one , Introduce the third mountain step by step . In fact, this topic is often asked in the interview , That's it Closure , To find out Closure what happened , Then we have to start with the principle , The principle is Scope . Therefore, this sub theme is to introduce Scope and closure , Chew off this hard bone , that Javascript The foundation of is quite solid , Entering a good enterprise is just around the corner . blunt !

Scope and closure

I believe most people have heard Closure The concept , but Closure What is the specific estimate? Few people can say it in detail . Tell the truth Closure It should be very common in our daily development , And in the front-end interview Closure It is also a common and important test site , Before you know about closures, let's take a look at Scope , Because this is Closure The key principle of .

One 、 Scope

Scope is actually a set of rules , Used to determine where and how to find variables . Simply put, you put forward the query request , But whether you can get what you want is determined by Scope decision .

Such as :var a = 1; How the compiler handles ?

  1. First , encounter var a, The compiler asks Scope Whether a variable with this name exists in a Scope in , If there is , Compiler ignored , Move on to the next step ; Otherwise, in the current Scope Declare a new variable named a;
  2. secondly , The compiler generates the code required for the engine to run , Used for processing a=1 Assignment of . When running, first ask Scope At present, there is a down payment called a The variable of , Use if any ; Otherwise, continue to search , Found assignment 1 to a, If there is no error .

that , How the engine looks up variables ?

The engine will be a variable a Conduct LHS Inquire about and RHS Inquire about .LHS Inquire about Also called Left query , It means that when the variable is on the left side of the assignment operation, it will be queried , The engine is going to find the container itself where the variables are stored , To assign values to variables . and RHS Inquire about Also called Right query , It refers to the query operation when the variable is on the right side of the assignment operator . In short, the left query occurs during assignment , The right query occurs when a variable is referenced .

1.1 Scope nesting

When a block or function is nested in another block or function , It happened Scope nesting . therefore , At present Scope When a variable cannot be found in , The search will continue in the nested scope , Until the variable is found .

function add(a) {
    console.log(a + b);
}
var b = 2;
add(1) // 3
 Copy code 

Just like the code here , to add() Method passes a parameter a, by a Copy to 1, But at this time add() There is no b Statement of , Just look up , Found... In global scope b, to b The assignment is 2, The final print result is 3.

1.2 Lexical scope

Scope There are two main working models : Lexical scope and dynamic scope .

Lexical scope In short, it is the scope defined in the lexical stage . Vernacular is where you write variables and scopes when you write code , That is, lexical scope , yes Static scope , When you write code, you decide .

1.3 Function scope

Function scope It means that all variables belonging to this function can be used and reused within the scope of this function . as follows :

var a = 1;
function foo() {
    var a = 2;
    console.log(a); // 2
}
foo();
console.log(a); // 1
 Copy code 

If you want to use Function scope , Then you have to define a function , This will make Global scope More than one function , It's polluted Global scope , And the function must be executed once to run the code block . Is there a way , Neither pollution Global scope , Functions can also be executed by themselves ?

That's what we're going to talk about next → Immediate execution function .

1.3.1 Immediate execution function

(function foo() {
    var a = 1;
    console.log(a); // 1
})();
 Copy code 

So that's one Immediate execution function , It can also be the following , as follows :

(function foo() {
    var a = 1;
    console.log(a); // 1
}());
 Copy code 

Notice that there are two '()', first () Make this function declaration a function expression , Besides, the second () Realized function call .

1.3.2 Block scope

If I haven't written Block scope Code for , But you will know the following code :

for(var i = 0; i < 5; i++) {
    console.log(i);
}
 Copy code 

You can see in the for The head of the loop defines the variable i, Because I want to be in for Use in loop i, But this ignores one thing :i Will be bound in the global scope .

ES6 Introduced let keyword , Provides another way to declare variables .

for(let i = 0; i < 5; i++) {
    console.log(i); // 0 1 2 3 4
}
console.log(i); // ReferenceError: a is not defined
 Copy code 

ES6 It also introduced const keyword , It's also a way to declare variables .

const a = 1;
const a; // Identifier 'a' has already been declared

const b; // Missing initializer in const declaration
 Copy code 

let、const and var The difference between :

  1. var  Declared variables have variable Promotion , That is, variables can be called before declarations , The value is undefined;let and const No variable promotion , That is, the variables they declare must be used after declaration , Otherwise, the report will be wrong ;
  2. var There is no temporary dead zone ;let and const There is a temporary dead zone , Only wait until the line that declares the variable appears , To get and use this variable ;
  3. var There is no block level scope ;let and const There are block level scopes ;
  4. var Allow variables to be declared repeatedly ;let and const Repeated declaration of variables in the same scope is not allowed ;
  5. var and let You can modify declared variables ;const Declare a read-only constant . Once declared , You can't change the value of a constant ;

notes : It works const Try to use const, Most other cases use let, Avoid using var

1.3.2 Variable Promotion

Variable Promotion It's in one Scope in , All declarations, including variables and functions, are first declared before any code is executed “ Move ” To the top of the scope .

 Example 1:
a = 1;
var a;
console.log(a); // 1

//  analysis :
var a;
a = 1;
console.log(a); // 1

 Example 2:
console.log(a); // undefined
var a = 2;

//  analysis :
var a;
console.log(a); // undefined
a = 2;
 Copy code 

You can find , When running var a = 2; when , There will be two stages : Compile phase and Execution phase .

Conclusion : First define and then assign .

  • Functions and variables are raised , But functions are promoted first , And then variables .
foo(); // 2
var foo = 1;

function foo() {
  console.log(2);
}

foo = function() {
  console.log(3);
}

//  Engine parsing :
function foo() {...}
foo()
foo = function() {...}
 Copy code 
  • Multiple functions with the same name , The latter will override the former :
foo(); // 3
var foo = 1;

function foo() {
  console.log(2);
}

function foo() {
  console.log(3);
}
 Copy code 
  • Ascension is not controlled by conditional judgment
foo(); // 2

if (true) {
  function foo() {
    console.log(1);
  }
} else {
  function foo() {
    console.log(2);
  }
}
 Copy code 

notes : Try to avoid ordinary var Declaration and function declaration are mixed together .

Okay , Here we are Scope The relevant knowledge is over , Actually Scope My knowledge is very basic , It is also the most involved in daily development , Just the usual development, just know how to use , Instead of pursuing its underlying principles , But you read this article , Then you should be able to master Javascript Medium Scope knowledge , These are all necessary for advanced needs ! Next, we will introduce the knowledge of closures , This is also the difficulty that must be mastered !

Reference material : Understand thoroughly JavaScript Scope and closure in —— author :kyrie The way to the front

Two 、 Closure

2.1 What is a closure ?

Closure : Functions in functions , The functions inside can access the variables of the functions outside , The outer variable is part of the inner function . Its essential principle is : The parent scope cannot directly access the variables in the child scope .

function outer(){
    var num = 0; //  Internal variables 
    return function add() { //  By returning add function , Can be in outer Outside visit 
        num++; //  Internal function reference , As add Part of the function 
        console.log(num);
    }
}

var func = outer();
func(); // 1
func(); // 2
 Copy code 

The above code is Closure . Under normal circumstances , When outer() After execution ,outer() Internal scopes are destroyed ( Garbage collection mechanism ), And closure's “ magical ” The point is that it can prevent this from happening . in fact outer() The internal scope still exists , Otherwise add() There's no access to outer() Variables in scope num.outer() After execution ,add() Still hold references to the scope , And this quote is called Closure .

2.2 The function of closures

The most basic function : You can return functions or methods through closures , Used to modify the data inside the function .

function bar() {
    var name = ' Zhang San ';
    var age = 18;
    return {
        getName: function() {
            return name;
        },`
        setName: func`tion(value) {
            name = value;
            return name;
        }
    }
}

var obj = bar();
console.log(obj.getName()) //  Zhang San 
console.log(obj.setName(' Li Si ')); //  Li Si 
console.log(obj.getName()); //  Li Si 
 Copy code 

Look at the code above , Originally, the external cannot access name Of , But after Closure Blessing , The outside can pass through getName() Methods to get name And can use setName() change name Value . This is it. Closure The most basic function , It can be used to modify the data inside the function .

Let's use it in the interview , The questions with the highest attendance rate to test the above learning results , as follows :

for(var i = 0; i < 5; i++) {
  setTimeout(function timer() {
    console.log(i);
  }, i * 1000)
}
 Copy code 

ask : What will this code output ? This is an old actor , The result is to print one... Every other second 4.

Then how to modify it to output in turn 0 To 4 As a result ?

First, use the immediate execution function , as follows :

for(var i = 0; i < 5; i++) {
  (function(i) {
    setTimeout(function timer() {
        console.log(i);
    }, i * 1000)
  })(i);
}
 Copy code 

You can also use let keyword , as follows :

for(let i = 0; i < 5; i++) {
  setTimeout(function timer() {
    console.log(i);
  }, i * 1000);
}
 Copy code 

thus , You should have a deep understanding of closures , If you don't understand , Look back a few more times , Try to analyze each line of code , Knock the code yourself , After all, a good memory is better than a bad pen , Try to understand it and learn it well , Just don't fall down again in the future job interview !

2.3 The defect of closure

  • The existence of closures may cause variables to reside in memory , Improper use can cause memory leaks
  • Memory leaks can cause applications to jam or crash

In fact, strictly speaking Closure Not a memory leak , Memory leaks are unexpected ( I hope it's recycled, but it's not recycled ), and Closure Is in line with expectations , Now that it's used Closure , Like the above, a function is returned so that you can modify name, Then you can't expect this data to be destroyed , So it is reasonable that it exists in memory , If it's destroyed, it can't be used . It's often said that “ Closures are memory leaks ”, It's actually an imprecise statement , In fact, it expresses Closure Your data cannot be garbage collected .

thus , Scope and closure The relevant knowledge of , This is what people often say Javascript The last of the three mountains , Congratulations on following this series over these three mountains , I believe there will be gains . Learning is not easy , You still have to watch it several times before you can deeply understand , Instead of collecting it, it means meeting , So in your spare time, you really have to turn more books , Just keep your head up !

Last ,xdm Look at the text so far , Give a compliment before you go ,3Q^_^

Excellent article in the past

Afterword

partners , If you think this article is of some help to you , Point or focus on walking ^_^ . In addition, if there are problems or incomprehensible parts in this article , Welcome to comment in the comment area and point out , Let's discuss and encourage .

copyright notice
author[MaybeIsAdog],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2022/04/202204291854184716.html

Random recommended