JavaScript:执行上下文与作用域链

本文主要参考《JavaScript高级程序设计(第4版)》,介绍了JavaScript的执行上下文与作用域链。执行上下文包含待执行代码,有全局和函数上下文之分,通过上下文栈调度。每个上下文有变量对象,函数调用还有活动对象。作用域链用于跨上下文访问变量和函数,还介绍了其增强、标识符查找等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

执行上下文与作用域链


主要参考资料:

  • 《JavaScript 高级程序设计(第4版)》
    • P87(112/931)
    • P309(334/931)

执行上下文

执行上下文 ,简称 上下文 ,包含需要被执行的代码。

执行上下文会在其代码执行完毕后被销毁。


上下文栈

JavaScript 维护了一个 上下文栈 ,用于调度上下文的执行。

上下文栈是一个栈,遵守先进先出的规则。

当上下文需要被执行时,上下文会被推到上下文栈。当上下文执行完后,上下文会被弹出上下文栈,将执行控制权交还给上下文栈中的上下文。

执行上下文主要分为两种:

  • 全局上下文,是最先被推到上下文栈的上下文。

    在浏览器中全局上下文是对象 window 。

  • 函数上下文,即局部上下文。

    每个函数调用都有一个上下文。

    当执行函数调用时,会为函数调用创建一个上下文。


变量对象

每个上下文都有一个 变量对象(Variable Object) ,即 作用域(Scope) ,用于存储在当前上下文中定义的变量和函数。


函数的活动对象

当执行函数调用时,会为函数调用创建一个 活动对象(Activation Object) ,存储了函数调用时创建的参数变量。

函数调用的活动对象(Activation Object)会被用作函数上下文的变量对象。


作用域链

当执行一个上下文时,会为上下文创建一个 作用域链(Scope Chain) ,用于实现跨上下文地访问变量和函数的操作。

作用域链是一个链表,遵守链表的规则。

作用域链包含了指向上下文栈中所有上下文的变量对象的指针。

即作用域链中的指针指向某个上下文的变量对象。

作用域链的顺序是上下文栈中上下文被执行的顺序。

即正在执行的上下文的变量对象位于作用域链的最前端。

通过作用域链,正在执行的上下文可以访问其它上下文的变量对象,从而获取在其它上下文中定义的变量和函数。

作用域链的顺序,决定了各级上下文中的代码在访问变量和函数时的顺序。


作用域链增强

当执行 try/catch 语句中的 catch 语句时,会临时创建一个变量对象,并将这个变量对象添加到作用域链的前端。这个变量对象包含了错误对象的声明。


标识符查找

当上下文被执行时,必须确定上下文中的标识符表示什么,即需要找到标识符的声明。

标识符查找,即在作用域链中搜索标识符的声明。

标识符查找从作用域链的最前端开始:

  • 如果在当前的作用域中找到标识符的声明,则搜索完成。
  • 如果在当前的作用域中没有找到标识符的声明,则继续沿作用域链逐级搜索,如果在某个作用域中找到标识符的声明,则搜索完成。
  • 如果遍历作用域链后,没有找到标识符的声明,则说明标识符没有声明,此时通常会报错。

可以看出,访问局部变量比访问全局变量快。

不过,JavaScript 引擎在优化标识符查找上做了许多工作,将来这个差异可能就微不足道了。(但无论如何优化,始终是有差异)


更多细节

在执行定义函数时,会创建一个当前上下文的作用域链,并保存在内部特性 [[Scope]] 中。

当执行函数调用时,会创建函数上下文,复制内部特性 [[Scope]] 创建作用域链,接着创建活动对象并将其添加到作用域链的前端。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值