我正在分析一些第三方javascript库,并遇到了一种方法,人们可以快速参考核心原型。这样做有什么性能上的好处吗?任何人都可以用一个例子来解释这个吗?
var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
// Create quick reference variables for speed access to core prototypes.
var
push = ArrayProto.push,
slice = ArrayProto.slice,
concat = ArrayProto.concat,
toString = ObjProto.toString,
hasOwnProperty = ObjProto.hasOwnProperty;
答案 0 :(得分:6)
这样做是否有任何性能优势?
非常小的,是的,有两个/三个原因:
当您引用标识符(例如,Array
或ArrayProto
或push
)时,JavaScript引擎首先查看当前的词法环境然后,如果不是发现,下一个,下一个,等等,直到它到达全球词汇环境。我假设您所指的代码在范围函数内。因此,因为它们是作用域范围内的本地人,所以它们立即被发现,而不是JavaScript引擎必须遍历全球环境才能找到它们。
Array.prototype
不仅需要查找Array
,还需要查找prototype
上的Array
属性。它不会花费任何可观的时间,但也不会花费零时间。
(重复#2排序)查看Array.prototype.push
还需要在push
上查找Array.prototype
。再一次,不值得,但也不是零。
因此,使用本地push
而不是Array.prototype.push
(等等),这些组合可以使非常小的性能差异。
更有可能,但,作者之所以这样做,是因为它减少了输入,而不是作为性能增强。 : - )
举一个例子:在不是数组的对象上使用Array.prototype.slice
之类的函数通常很有用。事实上,在ES2015的Array.from
之前,它是将类似数组对象(例如从querySelectorAll
返回的集合)转换为真实数组的规范方法之一(更多在我的回答中here)。
所以考虑到你的问题中的设置,如果我有类似数组的列表:
var list = document.querySelectorAll("some-selector-here");
而不是这样做以将该列表作为数组:
var trueArray = Array.prototype.slice.call(list);
我可以这样做:
var trueArray = slice.call(list);
由于slice
可能位于当前的词汇环境中,或者恰好位于其外部,因此发现它很快(上面的第1点),然后我们就完成了,而不是必须查找{ {1}}上的{1}}(上面第2点),然后在prototype
上查找Array
(上面第3点)。
所以非常稍快一些;但同样,主要是,它更短,更不容易出错。
答案 1 :(得分:0)
如果您要在函数中执行大量的Array.prototype,您可能希望将函数引用的副本获取到变量中以供重用。这将提供一个小的性能优势。