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 globalContext
denote 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---