【 js 基礎 】為什麼 call 比 apply 快?

來源:互聯網
上載者:User

標籤:添加   [1]   開始   基礎   index   tostring   正是   callable   一個   

這是一個非常有意思的問題。

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

 1 var triggerEvents = function(events, args) { 2     var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2]; 3     switch (args.length) { 4       case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return; 5       case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return; 6       case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return; 7       case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return; 8       default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return; 9     }10 };

( 代碼來自 backbone )

作者會在參數為3個(包含3)以內時,優先使用 call 方法進行事件的處理。而當參數過多(多餘3個)時,才考慮使用 apply 方法。這個的原因就是 call 比 apply 快。   網上有很多例子全方位的證明了 call 比 apply 快。大家可以看看 call和apply的效能對比 這篇文章中的例子,很全面。或者你也可以自己寫幾個簡單的,測試一下。這裡要推薦一個神奇網站 jsperf ,用於測試 js 效能。  幾個簡單的例子:

  為什麼call 比apply 快?這裡就要提到他們被調用之後發生了什麼。  

Function.prototype.apply (thisArg, argArray)

1、如果IsCallable(Function)為false,即Function不可以被調用,則拋出一個TypeError異常。
2、如果argArray為null或未定義,則返回調用function的[[Call]]內部方法的結果,提供thisArg和一個空數組作為參數。
3、如果 Type(argArray)不是Object,則拋出TypeError異常。
4、擷取argArray的長度。調用argArray的[[Get]]內部方法,找到屬性length。 賦值給len。
5、定義 n 為ToUint32(len)。ToUint32(len)方法:將其參數len轉換為範圍為0到2^32-1的2^32個整數值中的一個。
6、初始化 argList 為一個空列表。
7、初始化 index 為 0。
8、迴圈迭代取出argArray。重複迴圈 while(index < n)
            a、將下標轉換成String類型。初始化 indexName 為 ToString(index).
            b、定義 nextArg 為 使用 indexName 作為參數調用argArray的[[Get]]內部方法的結果。
            c、將 nextArg 添加到 argList 中,作為最後一個元素。
            d、設定 index = index+1
9、返回調用func的[[Call]]內部方法的結果,提供thisArg作為該值,argList作為參數列表。

 

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

1、如果 IsCallable(Function)為false,即Function不可以被調用,則拋出一個TypeError異常。
2、定義argList 為一個空列表。
3、如果使用超過一個參數調用此方法,則以從arg1開始的從左至右的順序將每個參數附加為argList的最後一個元素
4、返回調用func的[[Call]]內部方法的結果,提供thisArg作為該值,argList作為參數列表。


我們可以看到,明顯apply比call的步驟多很多。
由於apply中定義的參數格式(數組),使得被調用之後需要做更多的事,需要將給定的參數格式改變(步驟8)。 同時也有一些對參數的檢查(步驟2),在call中卻是不必要的。
另外一個很重要的點:在apply中不管有多少個參數,都會執行迴圈,也就是步驟6-8,在call中也就是對應步驟3 ,是有需要才會被執行。

綜上,call 方法比 apply 快的原因是 call 方法的參數格式正是內部方法所需要的格式。

 

 

 

 參考並學習:http://es5.github.io/#x15.3.4.3https://stackoverflow.com/questions/23769556/why-is-call-so-much-faster-than-apply   

【 js 基礎 】為什麼 call 比 apply 快?

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.