3

我看过一些文章解释使用 Javascript 中的作用域链解析变量。

他们都说变量是在运行时解析的,沿着作用域链遍历并迭代地寻找具有该名称的变量。我还看到了支持该主张的图表,说明了链上变量的不良性能,访问时间与距离范围级别的数量大致呈线性关系。

我不明白为什么访问时间不是恒定的。某个位置的变量名会创建一个常量字典绑定。所以我天真地认为,我们应该能够用对执行上下文的引用加上对相对于该执行上下文的变量的引用来表示相应的运行时变量引用实例。

你能否解释一下为什么不是这样。

4

1 回答 1

2

今天的 JIT 编译器(如 V8)可能会很好地优化其中的一些,但基本上它是这样工作的:

例如,有一堆这样的功能..

function foo() {
    function bar() {
    }
}

这将生成一个闭包foo和一个闭包bar。为了使变量查找起作用,解释器必须向上通过边界闭包来查找变量。

例如,在 中bar,变量可以定义在

  • 内部函数bar
  • 里面foo
  • 在全球范围内

所以这里取决于变量有多远,代码需要检查所有这些。

现在您当然可以保留某种变量名称表,其中查找始终保持不变,但随后您将面临另一个问题:阴影变量。

您可以在嵌套函数中为变量共享相同的名称。因此,在根据名称创建变量查找表时会出现问题。当然,您也可以根据可用的变量为每个函数复制并构建一个查找表,但这反过来又是速度与内存消耗的权衡。

在不了解当今 JS 引擎的全部细节或实现的情况下,很难说为什么它是这样设计的。但是,我认为这是一个足够合理的系统,因为它在不消耗大量内存的情况下运行良好。此外,如果您希望加快变量查找速度,您始终可以将变量分配到函数的本地范围内,因此您可以根据需要手动优化它。

于 2013-11-09T01:27:25.403 回答