最近我读过这篇文章performance guide Let's make the web faster并对“避免陷阱陷阱”建议感到困惑(好像这些建议是针对变量范围是动态的CommonLisp用户提供的):
var a = 'a'; function createFunctionWithClosure() { var b = 'b'; return function () { var c = 'c'; a; b; c; }; } var f = createFunctionWithClosure(); f();
调用
f
时,引用a
的速度比引用b
慢,这比引用c
要慢。
很明显,引用局部变量 c 比 b 快,但是如果iterpreter写得正确(没有动态范围 - 就像链式哈希表查找...)速度差应该只是微不足道的。或者不是?
答案 0 :(得分:4)
scope chain lookup
和prototype chain lookup
一样优化。意思是,AFAIK引擎试图保存某种带有访问节点的哈希表。
仅当调用eval()
(明确或隐式,例如setTimeout
)或try-catch
子句或a with statement
时,此方法才有效。由于这样的结构,解释器无法确定如何访问数据,它需要“回退”到经典的scope chain lookup
,这实际上意味着,它必须遍历所有父上下文variable / activation objects
和尝试解析搜索到的变量名称。
当然,这个过程将花费更多的时间来处理与开始查找处理的位置“相距很远”的对象/名称。这反过来意味着,访问global object
上的数据将始终是最慢的。
在您的代码段中,a
的查找过程就像
anonymous function -> Execution Context -> Activation Object (not found)
anonymous function -> Execution Context -> [[ Scope ]]
- createFunctionWithClosure
- global scope
createFunctionWithClosure -> Activation Object (not found)
global scope -> Variable Object (found)
所描述的查找程序适用于ECMAscript Edition 262第3版。 ECMAscript第5版在那里有一些根本性的变化。