我已经看过一些文章,用Javascript中的范围链解释变量的解析。
他们都说变量在运行时解析向上走范围链并迭代地查找具有该名称的变量。我还看到了支持这种说法的图表,说明了链中高位变量的不良表现,访问时间与距离的范围级别大致呈线性关系。
我不知道访问时间不恒定的原因。某个位置的变量名称会创建一个常量的词典装订。所以我天真地想,我们应该能够 表示相应的运行时变量引用实例,引用执行上下文以及相对于该执行上下文的变量引用。
你能否解释为何不这样做。
答案 0 :(得分:2)
今天像V8这样的JIT编译器可能会很好地优化其中一些,但基本上这就是它的工作原理:
例如,拥有一堆像这样的函数..
function foo() {
function bar() {
}
}
这将生成foo
的闭包和bar
的闭包。为了使变量查找起作用,解释器必须通过边界闭包来查找变量。
例如,在bar
中,可以在
bar
foo
所以这里取决于变量的距离,代码需要检查所有变量。
现在你当然可以保留某种变量名表,其中查找总是不变的,但是你面临另一个问题:阴影变量。
您可以为嵌套函数中的变量共享相同的名称。因此,这将在基于名称的变量查找表中出现问题。当然,您可以根据可用的变量为每个函数复制和构建查找表,但这最终会成为速度与内存消耗之间的权衡。
在不了解当今JS引擎的全部细节或实现的情况下,很难说它为何如此设计。但是,我认为这是一个足够合理的系统,因为它可以在不花费大量内存的情况下运行良好。此外,如果您希望加速变量查找,您始终可以将变量分配到函数的本地范围,因此您可以根据需要手动优化变量。