javascript 通过执行上下文来跟踪代码

60 篇文章 0 订阅
55 篇文章 1 订阅

在javascript中,代码执行的基础单元是函数。我们时刻使用函数,使用函数进行计算,使用函数更新UI,使用函数达到复用代码的目的,使用函数让我们的代码更容易理解。为了达到这个目标,第一个函数可以嗲用第二个函数,第二个函数可以调用第三个函数,以此类推。当发生函数调用时,程序会回到函数调用的位置。

 

JavaScript引擎是如何跟踪函数的执行并回到函数的位置的?

JavaScript代码有两种类型:一种是全局代码,在所有函数外部定义;

一种是函数代码,位于函数内部。JavaScript引擎执行代码时,每一条语句都处于特定的执行上下文中。

 

既然具有两种类型的代码,那么就有两种执行上下文:全局执行上下文和函数执行上下文。

二者最重要的差别时:全局执行上下文只有一个,当JavaScript程序开始执行时就已经创建了全局上下文;

而函数执行上下文是在每次调用函数时,就会创建一个新的。

 

注意:当调用函数时可通过关键字访问函数上下文。函数执行上下文,虽然也称为上下文,但完全是不一样的概念。执行上下文是内部JavaScript概念,JavaScript引擎使用执行上下文来跟踪函数的执行。

 

JavaScript基于单线程的执行模型:在某个特定的时刻只能执行特定的代码。一旦发生函数调用,当前的执行上下文必须停止执行,并创建新的函数执行上下文来执行函数。当函数执行完成后,将函数执行上下文销毁,并重新回到发生调用时的执行上下文中。所以需要跟踪执行上下文——正在执行的上下文以及正在等待的上下文。最简单的跟踪方法是使用执行上下文栈(或称为调用栈)。

 

注意:栈是一种基本的数据结构,只能在栈的顶端对数据项进行插入和读取。这种特性可类比于自助餐厅里的一叠托盘,你只能从托盘堆顶端拿到一个托盘,服务员也只能将新的托盘放在这叠托盘的顶端。

console.log("-------------------创建执行上下文-----------------------");
//一个函数调用另一个函数
function skulk(ninjaTest) {
    report(ninjaTest + " skulking!");
}
//通过内置的console.log方法发送消息
function report(message) {
    console.log(message);
}

//在全局中分别调用两个函数
skulk("Kuma");
skulk("Yoshi");

 

从上图中看出:执行上下文的行为如下:

1.每个JavaScript程序只创建一个全局执行上下文,并从全局执行上下文开始执行(在单页应用中每个页面只有 一个全局执行上下文)。当执行全局代码时,全局执行上下文处于活跃状态。

2.首先在全局代码中定义两个函数:skulk和report,然后调用skulk("Kuma")。由于在同一个特定的时刻只能执行特定代码,所以JavaScript引擎停止执行全局代码,开始执行带有Kuma参数的skulk函数。创建新的函数执行上下文,并置入执行上下文栈的顶部。

3.skulk函数进而调用report函数。又一次因为在同一个特定时刻只能执行特定代码。所以,暂停skulk执行上下文,创建新的Kuma作为参数的report函数的执行上下文,并置入执行上下文栈的顶部。

4.report通过内置函数console.log打印出消息后,report函数执行完成后,代码又回到了skulk函数。report执行上下文从执行上下文栈顶部弹出,skulk函数执行上下文重新激活,skulk函数继续执行。

5.skulk函数执行完成后也发生类似的事情:skulk函数执行上下文从栈顶端弹出,重新激活一直在等待的全局执行上下文并恢复执行。JavaScript的全局代码恢复执行。

skulk函数第二次执行时,整个过程也是类似的,只是参数变成了Yoshi。分别创建新的函数执行上下文skulk("Yoshi")和report("Yoshi skulking"),并依次置入执行上下文栈的顶部。

每个函数执行完成时,对应的函数上下文从执行上下文栈顶部弹出。

虽然执行上下文栈(execution context stack)是JavaScript内部概念,但仍然可以通过JavaScript调式器中查看,在JavaScript调试器中可以看到对应的调用栈(call stack)。

 

 

 

执行上下文除了可以跟踪应用程序的执行位置之外,对于标识符也是至关重要,在静态环境中通过执行上下文可准确定位标识符实际指向的变量。

 

参考《JavaScript忍者秘籍》

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值