爲何 call 比 apply 快?

這是一個很是有意思的問題。git

在看源碼的過程當中,總會遇到這樣的寫法:github

var triggerEvents = function(events, args) {
    var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
    switch (args.length) {
      case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
      case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
      case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
      case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
      default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return;
    }
};
複製代碼

( 代碼來自 backbone )數組

做者會在參數爲3個(包含3)之內時,優先使用 call 方法進行事件的處理。而當參數過多(多餘3個)時,才考慮使用 apply 方法。
這個的緣由就是 call 比 apply 快。
網上有不少例子全方位的證實了 call 比 apply 快。你們能夠看看 call和apply的性能對比 這篇文章中的例子,很全面。或者你也能夠本身寫幾個簡單的,測試一下。這裏要推薦一個神奇網站 jsperf ,用於測試 js 性能。
幾個簡單的例子:



爲何call 比 apply 快?
這裏就要提到他們被調用以後發生了什麼。

bash

Function.prototype.apply (thisArg, argArray)app

一、若是 IsCallable(Function)爲false,即 Function 不能夠被調用,則拋出一個 TypeError 異常。
二、若是 argArray 爲 null 或未定義,則返回調用 Function 的 [[Call]] 內部方法的結果,提供thisArg 和一個空數組做爲參數。
三、若是 Type(argArray)不是 Object,則拋出 TypeError 異常。
四、獲取 argArray 的長度。調用 argArray 的 [[Get]] 內部方法,找到屬性 length。 賦值給 len。
五、定義 n 爲 ToUint32(len)。
六、初始化 argList 爲一個空列表。
七、初始化 index 爲 0。
八、循環迭代取出 argArray。重複循環 while(index < n)
         a、將下標轉換成String類型。初始化 indexName 爲 ToString(index).
         b、定義 nextArg 爲 使用 indexName 做爲參數調用argArray的[[Get]]內部方法的結果。
         c、將 nextArg 添加到 argList 中,做爲最後一個元素。
         d、設置 index = index+1
九、返回調用 Function 的 [[Call]] 內部方法的結果,提供 thisArg 做爲該值,argList 做爲參數列表。jsp

Function.prototype.call (thisArg [ , arg1 [ , arg2, … ] ] )性能

一、若是 IsCallable(Function)爲 false,即 Function 不能夠被調用,則拋出一個 TypeError 異常。
二、定義 argList 爲一個空列表。
三、若是使用超過一個參數調用此方法,則以從arg1開始的從左到右的順序將每一個參數附加爲 argList 的最後一個元素
四、返回調用func的[[Call]]內部方法的結果,提供 thisArg 做爲該值,argList 做爲參數列表。測試


咱們能夠看到,明顯 apply 比 call 的步驟多不少。
因爲 apply 中定義的參數格式(數組),使得被調用以後須要作更多的事,須要將給定的參數格式改變(步驟8)。 同時也有一些對參數的檢查(步驟2),在 call 中倒是沒必要要的。
另一個很重要的點:在 apply 中無論有多少個參數,都會執行循環,也就是步驟 6-8,在 call 中也就是對應步驟3 ,是有須要纔會被執行。網站

綜上,call 方法比 apply 快的緣由是 call 方法的參數格式正是內部方法所須要的格式。ui


catch me:

知乎:李佳怡

相關文章
相關標籤/搜索