我想知道是否有人知道为什么 call这么快apply?在chrome中,它大约快了4倍,在firefox中大约是30倍,我甚至可以制作一个自定义原型,apply2它(在大多数情况下)的运行速度是2 倍apply(从角度来看的想法):
Function.prototype.apply2 = function( self, arguments ){
switch( arguments.length ){
case 1: this.call( self, arguments[0] ); break;
case 2: this.call( self, arguments[0], arguments[1] ); break;
case 3: this.call( self, arguments[0], arguments[1], arguments[2] ); break;
case 4: this.call( self, arguments[0], arguments[1], arguments[2], arguments[3] ); break;
case 5: this.call( self, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4] ); break;
case 6: this.call( self, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5] ); break;
case 7: this.call( self, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6] ); break;
case 8: this.call( self, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7] ); break;
case 9: this.call( self, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8] ); break;
case 10: this.call( self, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9] ); break;
default: this.apply( self, arguments ); break;
}
};
Run Code Online (Sandbox Code Playgroud)
那么有谁知道为什么?
Nit*_*Nit 15
参考ECMAScript语言规范5.1版(2011年6月):
在apply带有参数thisArg和argArray的对象func上调用该方法时,将执行以下步骤:
如果IsCallable(func)是false,则抛出TypeError异常.
如果argArray是null或undefined,那么
return调用[[Call]]内部方法的结果func,提供thisArg作为this值和空参数列表.
Type(argArray)不是Object,则抛出TypeError异常.len调用with参数的[[Get]]内部方法
.argArray"length"n是ToUint32(len).argList空虚List.index为0.index < nindexName是ToString(index).nextArg调用with 的[[Get]]内部方法
作为参数.argArrayindexNamenextArg为最后一个元素argList.index为index + 1.[[Call]]内部方法的结果func,提供thisArg作为this值和argList参数列表.当call使用参数thisArg和可选参数arg1,arg2等在对象func上调用该方法时,将执行以下步骤:
IsCallable(func)是false,则抛出TypeError异常.argList空虚List.arg1将每个参数作为最后一个元素追加argList[[Call]]内部方法的结果func,提供thisArg作为this值和argList参数列表.正如我们所看到的,apply指定的格式显着更重,并且由于需要更改参数的格式以及最终需要它们的方式,因此需要做更多的工作.由于输入格式的不同,
有许多检查apply不必要call.
另一个关键点是参数循环的方式(步骤4-12中apply,隐含在步骤3中call):apply无论实际有多少个参数,都执行整个循环设置,call所有这些都是只在需要时完成.
此外,值得注意的call是,没有指定实现步骤3的方式,这将有助于解释不同浏览器行为的巨大差异.
所以简要回顾:call比apply输入参数已经格式化为内部方法所需的更快.
请务必阅读以下评论以进一步讨论.
| 归档时间: |
|
| 查看次数: |
1405 次 |
| 最近记录: |