JavaScript execution context

For a long time, most people think that the order of execution of JavaScript code顺序执行

var foo = function () {

    console.log('foo1');

}

foo();  // foo1

var foo = function () {

    console.log('foo2');

}

foo(); // foo2

It all seems reasonable here, but it's not as simple as you think

looking at this code

function foo() {

    console.log('foo1');

}

foo();  

function foo() {

    console.log('foo2');

}

foo(); 

both times will print foo2

There are two problems involved here variable promotion (written before) function promotion

The JavaScript engine does not analyze and execute the program line by line, but executes it piece by piece. When a piece of code is executed, it will perform a "preparation work", and variable promotion function promotion is the preparatory work.

How is this piece of JavaScript divided?

executable code

What are the types of executable code in JavaScript?

There are three types, global code, function code, and eval code (escaping strings as objects).

For example, when a function is executed, preparation work will be carried out. The "preparation work" here,
let's use a more professional term, is called "execution context".

execution context stack

The next question is, we have written too many functions, how to manage so many execution contexts created?

So the JavaScript engine creates an execution context stack (ECS) to manage the execution context

To simulate the behavior of the execution context stack, let's define the execution context stack to be an array:

ECStack = [];

Imagine that when JavaScript begins to interpret and execute code, the first thing it encounters is the global code.

Therefore, during initialization, a global execution context is first pushed to the execution context stack.

We globalContextdenote it with , and only when the whole application ends,

ECStack will be emptied, so before the program ends, there is always a globalContext at the bottom of ECStack:

ECStack = [
    globalContext     //全局代码
];

Now JavaScript encounters the following code:

function fun3() {
    console.log('fun3')
}

function fun2() {
    fun3();
}

function fun1() {
    fun2();
}

fun1();

Since it is a stack, it must be first in, last out The above code can be handled like this

//上面代码执行完毕
//遇到fun1执行 加入栈
ECStack.push(<fun1> functionContext);
//fun1里面执行fun2 加入栈
ECStack.push(<fun2> functionContext);
//fun1里面执行fun2里面执行fun3 加入栈 
ECStack.push(<fun3> functionContext);
//fun3里面执行代码 fun3 弹出栈
ECStack.pop();
//fun2 执行完毕 弹出栈
ECStack.pop();
//fun1 执行完毕 弹出栈
ECStack.pop();
// javascript接着执行下面的代码,但是ECStack底层永远有个globalContext

answer questions

The last blog talked about the problem of static scope, so how to deal with the use of the execution context stack?

var scope = "global scope";
function checkscope(){
    var scope = "local scope";
    function f(){
        return scope;
    }
    return f();
}
checkscope();
ECStack.push(<checkscope> functionContext);
ECStack.push(<f> functionContext);
ECStack.pop();
ECStack.pop();
var scope = "global scope";
function checkscope(){
    var scope = "local scope";
    function f(){
        return scope;
    }
    return f;
}
checkscope()();
ECStack.push(<checkscope> functionContext);
ECStack.pop();
ECStack.push(<f> functionContext);
ECStack.pop();

Although the result is the same, the execution of the code is not the same

In order to explain the difference between the execution of the two functions in more detail, we need to explore what the execution context actually contains.

future update

---End of recovery content---

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325012200&siteId=291194637