2

我正在阅读“JavaScript:权威指南,第 6 版”,并在“3.10.3 范围链”部分(第 55 页)中指出 -

“如果我们将局部变量视为某种 实现定义对象的属性,那么还有另一种方式来考虑变量范围。”

有人可以解释“实现定义的对象”是什么意思吗?

4

2 回答 2

3

局部变量在内部表示为与词法环境的绑定,如规范所示(ES5 10.5 - 注意以下引用中的“env”指的是当前作用域的词法环境):

  • 对于代码中的每个VariableDeclarationVariableDeclarationNoIn d,按源文本顺序执行

    • dnd中的标识符

    • varAlreadyDeclared成为调用env 的HasBinding 具体方法并传递dn作为参数的结果。

    • 如果varAlreadyDeclared为假,则

      • 调用env 的CreateMutableBinding 具体方法,传递dnconfigureBindings作为参数。

      • 调用env 的SetMutableBinding 具体方法,传递dn、 undefined 和strict作为参数。

由于您无法以编程方式访问范围的词法环境,因此您看不到这些绑定。但这意味着您可以将局部变量视为此不可见对象的属性,就像全局变量成为全局对象(您可以访问)的属性一样。

在上面引用的部分的开头很好地总结了这个概念:

每个执行上下文都有一个关联的变量环境。在执行上下文中评估的 ECMAScript 代码中声明的变量和函数作为绑定添加到该变量环境的环境记录中。

要更详细地了解该过程,请查看方法的规范。CreateMutuableBindingsetMutableBinding

为了回答您的实际问题,在这种情况下,“实现定义的对象”是当前执行上下文的词法环境。

于 2013-01-15T14:46:18.950 回答
3

想想一个没有暴露给我们的抽象对象。它由实现定义,并且仅对实现可用——“实现”意味着将运行您的代码的 JavaScript 引擎。

例如,考虑以下函数:

function f(a,b) {
    var foo = 5;
    return a + b + foo;
}

在该函数范围内定义的变量和参数可以表示为如下所示的对象:

{
    a,
    b,
    foo
}

对象属性的值可以在函数执行期间发生变化。例如,如果您使用 调用函数f(1,2),则一旦函数执行开始,对象将如下所示:

{
    a: 1,
    b: 2,
    foo: undefined
}

foo分配后5,它将如下所示:

{
    a: 1,
    b: 2,
    foo: 5
}

考虑这个对象,就好像它是在函数内部声明的。因此,您可以在函数内部访问 , 和 的值abfoo不能在函数外部访问。

于 2013-01-15T14:47:43.237 回答