Javascript:为什么对闭包变量的访问可能很慢
Javascript: why the access to closure variable might be slow
最近我读了这本性能指南让我们让web更快,并对"避免闭包陷阱"的建议感到困惑(就好像这些建议是为变量作用域是动态的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快,但如果iterprepter写得正确(没有动态作用域,比如链式哈希表查找…),那么速度差异应该只是很小的。还是不?
你说得对。现代JS引擎将对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版有一些基本的更改
相关文章:
- 存储$http如何从$http函数(Angularjs)外部获取可访问变量中的响应
- 查询后websql成功回调无法访问变量
- 无法访问变量
- 从ajax调用成功内部访问变量
- 从子弹出子窗口访问变量
- 下划线模板无法访问变量
- Meteor Iron路由器通过[data]vs[params]访问变量
- CanvasJS-访问变量-访问属性toString的权限被拒绝
- 如何从嵌套函数中访问变量
- 在<%%中定义的访问变量>从<脚本></脚本>
- 自提交表单访问变量javascript
- 如何访问变量
- 稍后在链中访问变量
- 在 Javascript 中访问变量
- 在方法调用对象之外访问变量而不使它们全局化(可能吗?
- 如何从函数/实例外部访问变量
- 从另一个脚本源访问变量
- Meteor:跨所有 Meteor.method的访问变量
- 每次加载页面时,火狐附加组件访问变量
- 在另一个函数中访问变量,返回未定义的 - JavaScript