JavaScript是顺序执行嘛?

前言,如果要问到javaScript的执行顺序。写过javaSacript的开发者们都会有一个直观的印象,就是顺序执行: 如以下代码

var fun1 = function() {
    console.log(1);
};
fun1();
var fun2 = function() {
    console.log(2);
};
fun2();
// 1
// 2
复制代码

但是真的是这样吗?

function fun() {
    console.log(1);
}
fun();
function fun() {
    console.log(2);
}
fun();
// 2
// 2
复制代码

执行出来的是两个2。

为什么了?

这个因为javaScript在执行的时候并非一行一行的分析和执行程序,而是一段一段的分析执行。当执行某一段代码的时候,就是做一个“准工作”,比如第一个例子的变量提升和第二个的函数提升。

那这里又有问题,这个一段一段是怎么划分的了。又是在什么情况下才会做“准备工作”了。

可执行代码

引入一个概念,“可执行代码”。javaScript有三种可执行代码:全局代码、函数代码、eval代码。一段一段就是这里的一个一个的可执行代码块。每当执行到一个可执行代码时候,就会进行准备工作,这里的准备工作,就是执行上下文。

执行上下文栈

如果一个脚本中有很多可执行代码,就有很多的执行上下文,那javaSscript引擎是怎么管理这么多的执行上下文的了。这里javaScript会有一个执行上下文栈在管理众多的执行上下文。

举个例子:
funtion fun3 () {
    console.log(3);
}
funtion fun2() {
    fun3();
}
function fun1() {
    fun2();
}
fun1();
复制代码

当执行上诉例子脚本时,首先开始遇到的是全局代码,所以初始化的时候首先会想执行上下文栈(ECStack[])中压入一个全局执行上下文,用globalContext表示,并且只有当整个应用程序执行完毕的时候,ECStack才会被清空。所有ECStack在程序没有执行完毕时,底部永远有一个globalContext。然后我们来执行上诉脚本。

// 执行fun1();
ECStack.push(fun1Context); 

// ECStack = [globalContext, fun1Context];
// 把fun1的执行环境压如到执行上下文栈。发现fun1里面引用了fun2.

ECStack.push(fun2Context); 
// ECStack = [globalContext, fun1Context, fun2Context];
// 把fun2的执行环境压如到执行上下文栈。发现fun2引用了fun3

ECStack.push(fun3Context); 
// ECStack = [globalContext, fun1Context, fun2Context, fun3Context];

// 执行完fun3
ECStack.pop(fun3Context);
// ECStack = [globalContext, fun1Context, fun2Context];

// 执行完fun2
ECStack.pop(fun2Context);
// ECStack = [globalContext, fun1Context];

// 执行完fun1
ECStack.pop(fun1Context);
// ECStack = [globalContext];

// javascript接着执行下面的代码,但是ECStack底层永远有个globalContext

// 程序销毁
ECStack.pop(globalContext);
// ECStack = [];复制代码

转载于:https://juejin.im/post/5cc69ef55188252517255e29

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值