Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript:范围链/变量查找性能_Javascript - Fatal编程技术网

Javascript:范围链/变量查找性能

Javascript:范围链/变量查找性能,javascript,Javascript,我看过几篇文章,解释了如何在Javascript中使用作用域链解析变量 他们都说变量是在运行时解析的,在作用域链上遍历并迭代查找具有该名称的变量。我还看到了支持这一观点的图表,说明了链高层变量的糟糕性能,访问时间与距离范围级别的数量大致呈线性关系 我不明白为什么访问时间不是恒定的。某个位置的变量名创建一个恒定的词典绑定。所以我天真地认为,我们应该能够 用对执行上下文的引用加上对相对于该执行上下文的变量的引用来表示相应的运行时变量引用实例 您能解释一下为什么不是这样吗。今天的JIT编译器(如V8)

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

他们都说变量是在运行时解析的,在作用域链上遍历并迭代查找具有该名称的变量。我还看到了支持这一观点的图表,说明了链高层变量的糟糕性能,访问时间与距离范围级别的数量大致呈线性关系

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


您能解释一下为什么不是这样吗。

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

例如,有一系列这样的函数

function foo() {
    function bar() {
    }
}
这将为
foo
生成一个闭包,为
bar
生成一个闭包。为了让变量查找工作,解释器必须通过边界闭包查找变量

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

  • 内部功能
    bar
  • 内部
    foo
  • 在全球范围内
因此,在这里,根据变量向上的距离,代码需要检查所有变量

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

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

如果不了解当今JS引擎的全部细节或实现,就很难说它为什么会这样设计。然而,我认为这是一个足够合理的系统,因为它可以在不消耗大量内存的情况下正常运行。此外,如果您希望加快变量查找速度,则始终可以将变量分配到函数的局部范围中,因此,如果您愿意,可以手动对其进行优化