【人人都能读标准】10. 作用域链与闭包

本文为《人人都能读标准》—— ECMAScript篇的第10篇。我在这个仓库中系统地介绍了标准的阅读规则以及使用方式,并深入剖析了标准对JavaScript核心原理的描述。


8.执行环境我们说过,由ECMAScript代码创建的执行上下文会有一个词法环境的组件,指向一个环境记录器,这是每一条作用域链的起点。

9.作用域我们提到,每一个环境记录器都有一个[[OuterEnv]]字段指向另一个环境记录器,通过[[OuterEnv]]连接起来的所有环境记录器共同构成一条作用域链。并且,在那一节中我们已经多多少少已经见过作用域链在环境中的样子了:

for (var i = 1; i < 5; i++) {
    
    setTimeout(() => {
    
        console.log(i) //  ①
    }, i * 1000)
}

第一次执行到位置 ①,调用栈如下所示:

open-pic

本节,我会先讲标识符解析的算法,即在作用域链上查找标识符的具体过程;然后,我会讲作用域链的构建过程;最后,我会讲一个以作用域链为基础、且大家都非常关心的概念 —— 闭包。


标识符的解析

在执行代码的过程中,当需要解析某个标识符的时候,会获取当前执行上下文的词法环境,从词法环境指向的环境记录器开始,沿着作用域链依次查找标识符,直到找到标识符或者走完整条作用域链才结束。

我们可以从标识符identifier的求值语义看到详细的过程:

resolvebinding

以下我为你把这个过程使用中文进行概括(name为标识符):

  1. 执行ResolveBinding(name)
    1. 默认把变量env设置为当前执行上下文的词法环境;(
    2. 此时env是一个环境记录器;
    3. 如果处于严格模式,设置变量strict为true,否则,设置为false;
    4. 执行:GetIdentifierReference(env, name,strict)
      1. 如果env为null,返回一个表示解析失败的引用记录器。
      2. 调用env.HasBinding(name),查看name是否存在环境中:(
      3. 如果结果为true,返回一个表示该标识符的引用记录器(Reference Record);(
      4. 如果结果为false,通过env.[[OuterEnv]]获得外层环境记录器outer,然后递归地调用GetIdentifierReference(outer, name,strict);(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值