取消引用变量的闭包有用吗?
我不确定取消引用变量是否或何时有用(以提高性能)。
var x = a.b.c.d[some_key].f;
while (loop) {
do_something_with(x);
}
似乎比
while (loop) {
do_somthing_with(a.b.c.d[some_key].f);
}
Is that need or is this returned by smart JavaScript 引擎更好?
但我真正的问题是我是否应该这样做,例如在图书馆里。
(function() {
var slice = Array.prototype.slice;
Function.prototype.x = function x() {
var args = slice.call(arguments, 0);
...
};
})();
或者只是
Function.prototype.x = function x() {
var args = Array.prototype.slice.call(arguments, 0);
...
};
引擎无法自动改进这一点,因为它不知道 Array.prototype.slice 是否会在运行时发生变化。
那么:创建一个闭包来创建对切片函数的本地引用是否会使脚本更快?或者额外的闭包范围是否使其比访问 Array 属性“prototype”的属性“slice”慢?
I'm not sure whether or when it is useful (to improve performance) to dereference variables.
var x = a.b.c.d[some_key].f;
while (loop) {
do_something_with(x);
}
seems to be better than
while (loop) {
do_somthing_with(a.b.c.d[some_key].f);
}
Is that needed or is this done automagically by smart JavaScript engines?
But my actual question is whether I should do this, for example, in a library.
(function() {
var slice = Array.prototype.slice;
Function.prototype.x = function x() {
var args = slice.call(arguments, 0);
...
};
})();
or just
Function.prototype.x = function x() {
var args = Array.prototype.slice.call(arguments, 0);
...
};
The engine can't improve this automatically because it doesn't know whether Array.prototype.slice
might change during the run time.
So: does creating a closure for creating the local reference to the slice function make the script faster? Or does the additional closure scope make it slower than accessing the property "slice" of the property "prototype" of Array?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
出于此目的,“取消引用”实际上是一个令人困惑的词。事实并非如此,您只是在局部变量中缓存一些属性/方法。实际上,无论您是为了访问随机对象上的某些属性/方法还是使用 Array.prototype.slice 来访问这些属性/方法,都没有什么区别。一旦您多次访问这些深度嵌套的属性,它就变得很有意义。
老实说,“现代”浏览器确实对访问进行了很多优化。所有现代 js 引擎都使用内部查找表来访问属性。但是,您仍然希望缓存那些深层嵌套的内容,因为在较旧的引擎中,它将一路向下遍历所有涉及的对象来解决它。
使用本地缓存引用的另一个原因是,即使是现代 js 引擎也不会在使用某种显式或隐式
eval
机制后立即使用哈希查找。特别是 Internet Explorer <9 和 Firefox 3.5 在(原型)链中每增加一步都会导致严重的性能损失。
需要注意的是:不建议对对象方法使用本地缓存(就像使用
slice
方法一样)。许多对象使用this
来确定调用它们的上下文。将方法存储在局部变量中会导致this
绑定到全局对象
或null
。因此,请始终确保使用
method.call
调用此类方法来手动设置上下文。"Dereferencing" is actually a confusing word for that purpose. Its not that, you just cache some property/method in a local variable. It actually makes no difference whether you do it to access some property/method on a random object or do it with
Array.prototype.slice
. It makes a lot of sense as soon as you access those deeply nested properties more than once.Tbh, "modern" browsers do optimize the access quite a lot. All modern js engines uses internal look-up tables to accessed properties. However, you still want to cache those deeply nested stuff since in older engines, it would go the whole way down through all involved objects to resolve it.
One more reason to use local cached references is, that even modern js engines won't use a hash-lookup as soon as some kind of explicit or implicit
eval
mechanism is used.Especially Internet Explorer <9 and Firefox 3.5 incur a terrible performance penalty with each additional step into a (prototype) chain.
One word of caution: it is not very recommended to use local caching for object methods (like you do with the
slice
method). Many objects usethis
to determine the context in which they are beeing called. Storing a method in a local variable causesthis
to be bound toglobal object
ornull
.So always make sure to call such a method with
method.call
to set the context manually.如果您打算多次访问某个属性,请考虑将其分配给局部变量。然而,对于现代 JavaScript 引擎来说,这种微优化的影响很小,最重要的是编写能够表达您意图的代码。
If you intend to access a property more than once, consider assigning it to a local variable. However, for modern javascript engines such micro-optimisations will make very little difference, the most important thing thing is to write code that expresses your intent.
对于这个特定问题,您无论如何都希望有一个实用函数:
...或者如果您关心性能:
您不希望在整个代码中使用
slice.call
构造。 ..For this particular issue, you want to have a utility function for that anyway:
... or if you care about performance:
You don't want to have that
slice.call
construct all over your code...