最近開發的過程中遇到了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。
話不多說,上代碼:
call的用例代碼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
apply的用例代碼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();
bind的用例代碼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