簡體   English   中英

為什么打電話比申請快得多?

[英]Why is call so much faster than apply?

我想知道是否有人知道為什么 callapply快得多? 在chrome中,它大約快4倍,在firefox中大約30倍,我甚至可以制作一個自定義原型, apply2 ,它(在大多數情況下)運行速度和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;
    }   
};

那么有誰知道為什么?

參考ECMAScript語言規范5.1版(2011年6月)

15.3.4.3 Function.prototype.apply(thisArg,argArray)

在帶有參數thisArg和argArray的對象func上調用apply方法時,將執行以下步驟:

  1. 如果IsCallable(func)false ,則拋出TypeError異常。

  2. 如果argArraynullundefined ,則return調用func[[Call]]內部方法的結果,將thisArg作為this值和空參數列表提供。

  3. 如果Type(argArray)不是Object ,則拋出TypeError異常。
  4. len是使用參數"length"調用argArray[[Get]]內部方法的argArray
  5. nToUint32(len)
  6. argList為空List
  7. index為0。
  8. index < n重復
  9. indexNameToString(index)
  10. nextArg是調用nextArg[[Get]]內部方法的argArray其中indexName作為參數。
  11. 附加nextArg作為最后一個元素argList
  12. index設置為index + 1
  13. 返回調用func[[Call]]內部方法的結果,提供thisArg作為this值,並將argList作為參數列表。

15.3.4.4 Function.prototype.call(thisArg [,arg1 [,arg2,...]])

在帶有參數thisArg和可選參數arg1,arg2等的對象func上call方法時,將執行以下步驟:

  1. 如果IsCallable(func)false ,則拋出TypeError異常。
  2. argList為空List
  3. 如果使用多個參數調用此方法, argList arg1開始以從左到右的順序將每個參數附加為argList的最后一個元素
  4. 返回調用func[[Call]]內部方法的結果,提供thisArg作為this值,並將argList作為參數列表。

正如我們所看到的,指定apply的格式顯然更重,並且由於需要更改參數的格式以及最終需要它們的方式,因此需要做更多的工作。
還有在一些測試, apply其不在需要call由於輸入格式的差別。

另一個關鍵點是參數循環的方式(在apply步驟4-12,隱含在call第3步中):循環的整個設置在apply執行,而不管實際上有多少參數,在call只有在需要時才能完成所有這些工作。
另外值得注意的是,沒有指定call步驟3的方式,這有助於解釋不同瀏覽器行為的巨大差異。

所以簡要回顧一下: callapply更快,因為輸入參數已經根據內部方法的需要進行了格式化。

請務必閱讀以下評論以進一步討論。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM