最近在使用jQuery的$.each方法時很,忽然想到$.each($('div'),function(index,entity){});中的這個index和entity是哪冒出來的,並且無關緊要的,並且這麼高大上的能告訴咱們當前遍歷的下標和實例。因此看了一下jQuery源代碼,是這麼寫的:javascript
調試的時候走的是標紅的這段代碼,而後用到了callback.call這個函數,因而翻看了一下《js高級程序設計》,其中有比較深的解釋。java
首先,function是一個指向Function對象,函數名是一個指向函數的指針。那麼在函數體內,就會有一個做用域,即this關鍵字。數組
this關鍵字指的是函數運行的做用域,舉個例子來講,app
<script type="text/javascript"> function funcA() { alert(this); alert("Function A"); } </script>
上面這段代碼中的函數funcA定義在全局環境中,那麼函數體內的this即window對象。函數
下面該到call和apply的說明了。以call函數爲例,call的第一個參數,就是改變函數的做用域,後面的參數爲傳入函數的所需的參數,必須與原函數的參數一直,舉例說明:學習
<script type="text/javascript"> var testO = { name: "Lily" }; function funcA(a,b) { alert(this); alert("Function A"); } function funcB(a, b) { funcA.call(testO, a, b); } funcB(1,2); //this變成了testO </script>
咱們定義funcB函數的中,調用了funcA的call函數,這個時候咱們改變了funcA中this的指向,本來指向window的,如今指向了call的第一個參數testO這個對象。並且調用call時,由於funcA函數有兩個參數,因此若是要想funcA傳遞參數,必須一一指出參數,即後面的兩個參數a和b,或者能夠只穿第一個參數this
即:funcA.call(testO);或者只傳a,即:funcA.call(testO,a);spa
而apply與call的區別僅在於,apply的第二個參數能夠是數組形式,並且沒必要一一指出參數,funcA.apply(testO,[a,b])設計
介紹完call與apply的基本用法,該說說他哥倆真正的用武之地了,擴充函數賴以運行的做用域。指針
<script type="text/javascript"> window.color = "透明"; var testObj = { color: "紅色" }; function testFuc() { alert(this.color); } $(function () { 1.testFuc(); //彈出「透明」 2.testFuc(this); //彈出「undefined」 3.testFuc.call(this.parent); //彈出「透明」 4.testFuc.call(window); //彈出「透明」 5.testFuc.call(testObj); //彈出「紅色」 }); </script>
上面這段代碼演示了call的做用。第一個函數調用,this指向了window,因此彈出了window的color屬性。
第二個函數可能有些朋友覺得也會彈出透明,可是請先肯定咱們的函數運行在$(function(){});中,這個jQuery的函數,瞭解jQuery的朋友都很清楚,在
$(function(){});中this的做用域指向的是document,而後咱們調用testFunc,要彈出document的color,固然是未定義的。
第三個函數將testFunc的this指向了document的親爹window,彈出window的color固然也是沒有問題的。
第四個函數就更加直白了,把window傳進去了
第五個函數,將testFunc的this指向了testObj,彈出了紅色。
講到這裏,用法你們應該都有所瞭解了,可是具體怎麼去理解怎麼去使用仍是看本身的套路。
我是這麼理解的,能夠把這種用法當作是C#或者java中的泛型方法。好比一個C#方法的定義
public void Test<T>(T a, T b) { }
這樣咱們就能夠實現對方法的擴展,實現通用的目的。
以上都是本人本身的見解和觀點,有什麼不對之處還請你們指出來共同窗習。