【问题标题】:Lexical environment and function scope词法环境和功能范围
【发布时间】:2012-09-17 23:23:49
【问题描述】:

javascript 中的词法环境和作用域是一回事吗?

【问题讨论】:

    标签: javascript function


    【解决方案1】:

    这是规范中关于 lexical environments 的内容:

    词法环境是一种规范类型,用于根据 ECMAScript 代码的词法嵌套结构定义标识符与特定变量和函数的关联。词法环境由环境记录和对外部词法环境的可能为空的引用组成。

    基于此,我会说是的,这就是人们说“范围”时通常所说的。

    尽管可能有人认为“范围”实际上定义为“Declarative Environment Record”:

    每个声明性环境记录都与一个包含变量和/或函数声明的 ECMAScript 程序范围相关联。声明性环境记录绑定由包含在其范围内的声明定义的标识符集。

    如果您将“范围”视为包含标识符和值之间的绑定的事物,那么第二个定义可能更适合。如果您将其视为知道其祖先作用域的东西,那么第一个定义更合适。

    编辑:第三个​​选项是“Execution Context”。

    【讨论】:

    • 第二个定义指的是“范围”,所以不能是“范围”本身的定义。
    • 可以。问题是关于“编程”范围。第二个定义使用单词范围的“​​正常”(如果你愿意的话,可以用字典)英文定义。
    • 我认为变量/函数的范围确实是当前执行上下文词法环境是正确的。参见“9.2.4 函数初始化”(ecma-international.org/ecma-262/8.0/#sec-functioninitialize):“...作用域指定的词法环境”。这是一个非常可靠的提示。
    【解决方案2】:

    词法环境是编写它的函数的环境。也就是说,它所在的静态顺序/位置,无论从哪里调用它。

    变量/函数的范围基本上是变量可见/可访问的位置。

    执行上下文是运行时任何时候执行堆栈的状态。那就是当前的执行上下文。

    【讨论】:

    • 如果我在此之前没有阅读其他答案,那会有点令人困惑,但我认为这个答案最好地总结了一种简单的方法来理解和区分词汇环境和范围。
    【解决方案3】:

    根据我刚刚从“Javascript Ninja 的秘密,2/e”中学到的内容给出答案--

    它们是不同的概念但又是相关的,我们需要定义一个相关的概念——Execution Context & it's stack来理解。

    执行上下文 & 执行上下文堆栈执行上下文是用于跟踪函数或全局代码执行的内部javascript构造。 js引擎维护了一个栈数据结构——执行上下文栈调用栈,里面包含了这些上下文,全局执行上下文留在底层这个堆栈的。当函数开始执行时,会创建一个新的执行上下文并将其推送到堆栈中。特定的执行上下文跟踪相应函数的语句正在执行的指针。当相应函数的执行完成时,会从堆栈中弹出一个执行上下文。

    词法环境:它是内部 js 引擎构造,它包含 标识符变量映射。 (这里的identifier是指变量/函数的名称,variable是对实际对象[包括函数类型对象]或原始值的引用)。词法环境还包含对父词法环境的引用。

    现在,对于每个 执行上下文 -- 1) 都会创建一个相应的词法环境,并且 2) 如果在其中创建了任何函数执行上下文,对该词法环境的引用存储在该函数的内部属性([[Environment]])中。因此,每个函数都会跟踪与其创建的执行上下文相关的词法环境。

    每个词法环境都会跟踪它的父词法环境(父执行上下文的环境)。结果,每个函数都有一个附加的词法环境链。 [注意:在js中函数是一个对象,通过语句创建一个函数就是创建一个Function类型的对象。所以像其他对象一样,函数可以保存内部和用户定义的属性]

    作用域 :它是与语言无关的概念,指的是变量或函数对执行代码的可见性。在 js 中,变量或函数对执行代码是可见的,如果它在当前词法环境中或在封闭函数的词法环境链中。如果是全局代码,则链不存在。

    希望你现在明白了..

    注意:类似于函数的情况,通过在es6中引入let和const,当一个块开始执行时(if块,for循环 块等),还创建了一个新的词法环境,其父函数的词法环境作为父函数。

    【讨论】:

    • 不知道这个回复是否也适用于ES6(你参考的书是在ES6发布之前出版的)
    • ES6 于 2015 年 6 月定稿,本书(第 2 版)于 2016 年 9 月出版
    • 这对我来说很有趣 [[Environment]] 和 [[Scope]] 内部属性有什么不同?
    • @MuradSofiyev,没有内部 [[Scope]] 属性。在ECMAScript 5.1 中提到了它,但是从ECMAScript 6th 开始,它被替换为 [[Environment]] 内部属性。所以我想它们大多是一样的。
    • 说函数的词法环境跟踪它的父词法环境不是更准确吗?而不是函数跟踪它的父词法环境,因为作用域链的所有魔力都是词法环境链
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-27
    • 2011-12-03
    相关资源
    最近更新 更多