Explain JS scope and scope chain in detail

The knowledge of scope and scope chain is the focus of JS. Eight out of ten interviews will ask you about this knowledge, so this part is very important. Let's take a good understanding of scope and scope chain. What exactly is it:

First the previous piece of code:

var a = 'jack';
function fn() {
    var a = 'frank';
}
console.log(a);

We define a variable a in the function, and a variable a outside the function, so which value of a should be output at the end?

At this time, there is the concept of scope. Simply put, scope is to restrict a variable to be valid only in a certain area .

The scope is divided into global scope and local scope, and the same is true for variables. In the above example, the first a is obviously a global variable, and the a in the function is obviously a local variable. Global variables have global scope and local variables have local scope. In this question, console.log calls a globally, so there is no doubt that the final output must be 'jack'.

At this time, I changed the function code block to the if code block to see what should be output in the end

var a = 'jack';
if(true) {
    var a = 'frank';
}
console.log(a);

The final result a outputs 'frank'.

In fact, there is a big hole here. Don't think that the curly brackets must be closed. After the statement in the if is executed, it will be automatically destroyed, but the variable defined inside the if in javascript will become the current execution. environment variables. The current execution environment is at the outermost periphery, so a in if becomes a global variable

Let's look at what the following code should output?

for(var i = 0;i<3;i++) {
    break;
}
console.log(i);
k = 5;
while(k>1) {
    k--;
    var d = 10;
}
console.log(k);
console.log(d);

In addition to the if code block and our common for loop, the while loop also has similar results. We should not be confused by the parentheses. The variables defined in the parentheses are not necessarily local scopes , so the i, k, d variables here are all is a global variable, this is the output:

The following is a general overview of the new block-level scope in ES6:

  • In ES6, as long as { } is not combined with a function, it should be "block-scoped".
  • In block scope, variables defined by var are global variables and variables defined by let are local variables.
  • In the local scope, that is, the function scope, whether a variable defined with var or a variable defined with let is a local variable.
  • Whether in block scope or local scope, omitting the var or let in front of the variable becomes a global variable.

Now let's go back to the previous example, this time add the global variable b, add two console.log output statements in the function, and finally call the function, but the variable b is not defined in the function, then the final will be what's the result

var a = 'jack';
var b = 'andy';
function fn() {
    var a = 'frank';
    console.log(a);
    console.log(b);
}
fn();
console.log(a);

Output result:

Why does the second console.log output the global variable andy?

At this time, we have the concept of scope chain. Simply put, the scope represents the area, and the scope chain represents the order. 

Now we put our eyes on the function fn. The first line defines a as a local variable, and the second line outputs this a, but there are two a's defined in the whole code, so we need the scope chain just mentioned to decide in the end Which variable to use first.

JavaScript will first check whether there is this variable a in the function. If it does not go to the periphery of the function to see if there is this variable, the scope chain here will help us arrange the order.

Therefore, the variable a is defined as 'frank' in the function, then the second line will output 'frank', and the third line will output the variable b, we first see if there is this variable in the function, and find no, and then go to the periphery to find that there is Global variable b, then the output is this value, let's look at the last console.log(a), because it is in the global scope, so only the global variable a can be accessed.

That is: the scope chain can only look up, and finally find the global. Cannot peer (locally) or look down

Let's look at this piece of code again:

var a = 'jack';
function fn() {
    console.log(a);
    var a = 'andy';
    console.log(a);
}
fn();

Let's think about what will be the output?

Output result:

 Students with a little js experience should all answer correctly, because there is a variable promotion , the variable a is declared in the first line, but it is not assigned a value. Let's modify the code below, and let's see what will be output:

var a = 'jack';
function fn() {
    console.log(a);
    var a = 'andy';
    console.log(ss());
    function ss() {
        return a;
    }
}
fn();

We add another function ss inside the fn function and call this function at the top of the function. Not only variables declared within functions will be hoisted, but functions within functions will also be hoisted, and function hoisting will take precedence over variables

So, in javascript this code is actually executed like this:

var a = 'jack';
function fn() {
    function ss() {
        return a;
    }
    var a;
    console.log(a);
    a = 'andy';
    console.log(ss());
}
fn();

First lift the function declaration to the first line, then declare the variable a, then output a, a is not assigned, so it is undefined, then a is assigned to 'andy', and finally the function ss is called, and the return is andy.

Guess you like

Origin blog.csdn.net/qq_49900295/article/details/124032755