let和const如何适合当前的执行上下文?他们每次都创建一个新的吗?

问题描述 投票:1回答:1

所以,我一直在阅读有关闭包,范围,词法环境和执行上下文的内容。根据我的理解,当前的执行上下文具有一个词法环境和一个变量环境(通过读取堆栈溢出时的其他线程,这似乎是一种特殊的词法环境,我发现它在ECMAScript 2016中提到但未定义)。变量环境具有使用var声明的标识符以及与它们关联的值。词汇环境在其记录中的某个位置具有由let和const声明的变量的绑定和值。我对此有一些疑问。

是可变环境只是词汇环境中的可变环境记录(由于某种原因记录部分已经掉了),还是一个单独的词汇环境,其中有一个外部词汇环境引用了某个东西(外部变量环境或外词法环境)?

此外,闭包和合并范围在此图中适合什么地方?据我了解,作用域是当前执行上下文可访问的内容,而仅仅是可访问内容的概念或范围的定义还包括JavaScript搜索变量,研究当前词法环境和变量环境的方式范围链上的后续环境?关于闭包,MDN将闭包定义为“捆绑在一起(封闭)的函数与对其周围状态(词汇环境)的引用的组合”,我看到它在ECMAScript 2016中多次使用-闭包只是新函数的开始执行上下文,因为它们确定词法环境(变量环境如何)并且它们“包含”函数?

最后,在当前执行上下文中,带有let和const的变量存储在哪里?我在几个Stack Overflow线程中看到它们处于词法环境中(从Google搜索中我什么都找不到)-具体来说,这里的第一个答案(Where are global let variables stored?)说:“因为您使用let而不是var,它存储在与全局词法环境对象关联的声明性环境记录中,而不是存储在全局对象本身上。”我认为总体上是一样的。那么这种情况呢:

function foo() {
    let a = 1;
    {
        let a = 2;
        console.log(a)
    }
    console.log(a)
}

foo()

这里会发生什么-名为“ a”的两个变量不能在相同的词法环境中,对吗?因此,存在两种词汇环境,但是第二种词汇环境是如何创建的。是否在新块的开头创建了新的执行上下文?这是否会发生在每个块中,或者仅发生在使用let和const声明了新变量的块中?

对不起,所有问题,但是我的主要问题是最后一个,我不了解理解的基础,这就是为什么我问所有问题。谢谢您的时间。

javascript const let
1个回答
0
投票

这里确实有几个问题。

MDN将closure定义为:

闭包是捆绑在一起(封闭)的函数和对其周围状态(词汇环境)的引用的组合。换句话说,闭包使您可以从内部函数访问外部函数的范围。在JavaScript中,每次创建函数时都会在函数创建时创建闭包。

希望这里的“换句话说”部分有助于“词法环境”的含义。

通过对比,letconst的作用域为该块。从MDN

let允许您声明限制在块语句或使用它的表达式的范围内的变量,这与var关键字不同,var关键字在全局范围内定义变量,或在整个函数中局部定义,而不管块范围如何。 ...

因此它基本上是相同的,除了范围是块级而不是功能级。

“全局词法环境对象”与“全局对象”之间的区别

Global对象基本上意味着将全局变量作为属性添加到window对象。请注意此示例中的差异(假定此代码在全局范围而不是在函数中运行):

let t = 4;
console.log(t, window.t); // window.t will be undefined
// --> 4, undefined

var q = 4;
console.log(q, window.q); // window.q will equal the global q
// --> 4, 4

两个名为“ a”的变量不能在同一词法环境中吗?

*编辑:经过更多阅读之后,我发现我以为我对词汇环境的了解不是很准确。看着ecma-262 specs,这似乎为主题提供了一些启示:

词法环境由环境记录和对外部词法环境的可能为空的引用组成。通常,词汇环境与ECMAScript代码的某些特定语法结构相关联,例如FunctionDeclaration,BlockStatement或TryStatement的Catch子句,并且每次评估此类代码时都会创建一个新的词汇环境。

因此,可以相对确定地在您的示例中,该块获得了自己的词法环境,带有对函数体的外部词法环境的引用/指针,依此类推。

ecma specs中有关letconst的部分也有一个有趣的区别:

[实例化包含变量的Lexical Environment时创建了变量,但是在评估了变量的LexicalBinding之前,不能以任何方式对其进行访问。

© www.soinside.com 2019 - 2024. All rights reserved.