JavaScript 中call()、 apply()、 bind()改變this指向理解


  最近開發的過程中遇到了this指向問題,首先想到的是call()、apply()、bind()三個方法,有些時候這三個方法確實是十分重要,現在我們就把他們的使用方法及異同點講解一下。

  1、每個函數都包含三個非繼承而來的方法,call()方法、apply()方法和bind()方法

      2、相同點:三者的作用都是一樣的,都是在特定作用中調用函數,等於設置函數體內this的值,以擴充函數賴以運行的作用域。

  一般來說,this總是指向調用某個方法的對象,但是使用call()、apply()和bind()方法時,就會改變this的指向。

  3、不同點:

    1)、bind()方法會返回一個函數,將接受多個參數的函數變換成接受一個單一參數。

      注意:bind(thisArg[, arg1[, arg2[, ...]]]), 將接受多個參數的函數變換成接受一個單一參數。bind()方法所返回的函數的length(形參數量)等於原函數的形參數量減去傳入bind()方法中的實參數量(第一個參數以后的所有參數),因為傳入bind中的實參都

      會綁定到原函數的形參。

    2)、apply()方法 接收兩個參數,一個是函數運行的作用域(this),另一個是參數數組。

      注意:apply([thisObj [,argArray] ]);,調用一個對象的一個方法,2另一個對象替換當前對象。如果argArray不是一個有效數組或不是arguments對象,那么將導致一個TypeError,如果沒有提供argArray和thisObj任何一個參數,那么Global對象

      將用作thisObj。

    3)、call()方法 第一個參數和apply()方法的一樣,但是傳遞給函數的參數必須列舉出來。

      注意:call([thisObject[,arg1 [,arg2 [,...,argn]]]]);,應用某一對象的一個方法,用另一個對象替換當前對象。call方法可以用來代替另一個對象調用一個方法,call方法可以將一個函數的對象上下文從初始的上下文改變為thisObj指定的新對象,如果沒有

      提供thisObj參數,那么Global對象被用於thisObj。

   話不多說,上代碼:

  

 1 //例1
 2     <script>
 3         window.color = 'red';
 4         document.color = 'yellow';
 5 
 6         var s1 = {color: 'blue' };
 7         function changeColor(){
 8             console.log(this.color);
 9         }
10 
11         changeColor.call();         //red (默認傳遞參數)
12         changeColor.call(window);   //red
13         changeColor.call(document); //yellow
14         changeColor.call(this);     //red
15         changeColor.call(s1);       //blue
16 
17     </script>
18 
19     //例2
20     var Pet = {
21         words : '...',
22         speak : function (say) {
23             console.log(say + ''+ this.words)
24         }
25     }
26     Pet.speak('Speak'); // 結果:Speak...
27 
28     var Dog = {
29         words:'Wang'
30     }
31 
32     //將this的指向改變成了Dog
33     Pet.speak.call(Dog, 'Speak'); //結果: SpeakWang
call的用例代碼
 1 //例1
 2     <script>
 3         window.number = 'one';
 4         document.number = 'two';
 5 
 6         var s1 = {number: 'three' };
 7         function changeColor(){
 8             console.log(this.number);
 9         }
10 
11         changeColor.apply();         //one (默認傳參)
12         changeColor.apply(window);   //one
13         changeColor.apply(document); //two
14         changeColor.apply(this);     //one
15         changeColor.apply(s1);       //three
16 
17     </script>
18 
19     //例2
20     function Pet(words){
21         this.words = words;
22         this.speak = function () {
23             console.log( this.words)
24         }
25     }
26     function Dog(words){
27         //Pet.call(this, words); //結果: Wang
28        Pet.apply(this, arguments); //結果: Wang
29     }
30     var dog = new Dog('Wang');
31     dog.speak();
apply的用例代碼
 1 var test = {
 2     a : 5,
 3     b : 6,
 4     sum : function (a,b) {
 5         var self = this;
 6         function getA() {
 7             return self.a;
 8         }
 9         function getB(){
10             return self.b;
11         }
12         alert(a);
13         alert(b);
14         return getA() + getB();
15     }
16 }
17 var obj = {a:2,b:3};
18 alert(test.sum.call(obj,4,5));      // 調用時self = this = obj,alert順序4,5,5
19 alert(test.sum.apply(obj,[6,7]));   // 調用時self = this = obj,alert順序6,7,5
20 var sum = test.sum.bind(obj,8);     // 此處返回一個只有一個參數的函數sum(b)
21 alert(sum(9));                      // 調用時self = this = obj,alert順序8,9,5
bind的用例代碼

 

   

  總結:

 

    1、call 、bind 、 apply 這三個函數的第一個參數都是 this 的指向對象

 

    2、call的參數是直接放進去的,第二第三第n個參數全都用逗號分隔

 

    3、apply的所有參數都必須放在一個數組里面傳進去

 

    4、bind除了返回是函數以外,它的參數傳遞方式和call 一樣。    

 

    當然,三者的參數不限定是string類型,允許是各種類型,包括函數 、 object 等等!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM