Javascript:作用域链/变量查找性能

Javascript: Scope chain / Variable lookup performance

本文关键字:变量 查找 性能 作用域 Javascript      更新时间:2023-09-26

我看过几篇文章,解释了在Javascript中使用作用域链解析变量。

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

我不明白为什么访问时间不是恒定的。某个位置的变量名称创建恒定的词典绑定。所以我天真地想,我们应该能够表示相应的运行时变量引用实例,其中包含对执行上下文的引用以及对相对于该执行上下文的变量的引用。

你能解释一下为什么不是这样吗?

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

例如,拥有一堆这样的功能。

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

这将生成foo的闭包和bar的闭包。为了使变量查找正常工作,解释器必须向上浏览边界闭包才能找到变量。

例如,在bar中,可以在

  • 内部功能bar
  • 内部foo
  • 在全球范围内
因此,根据变量的

上行距离,代码需要检查所有这些变量。

现在,您当然可以保留某种变量名称表,其中查找始终是恒定的,但是您会遇到另一个问题:阴影变量。

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

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