通俗易懂------this指向


因為JavaScript 中this 是在運行期進行綁定的,因此JavaScript 中this 關鍵字具備多重含義。

具體在實際應用中,this的指向大致可以分為下面4種。

  1. 作為對象的方法調用   obj.a()
  2. 作為普通函數調用    a()
  3. 構造函數調用        var b = new a(); 
  4. function.prototype.call或function.prototype.apply調用

作為對象的方法調用 和 作為普通函數調用

 1 window.a = 2;
 2 var obj = {
 3     a:1,
 4     getA:function(){
 5         console.log(this.a);
 6     }
 7 }
 8 obj.getA();       //輸出1,作為對象的方法調用,this指向當前對象
 9 var x = obj.getA;
10 x();   //輸出2,作為普通函數調用,this全部指向window對象。 

注意,不管x之前是obj.getA,還是其他某個對象的屬性,只要最后是以x(),fun()這種方式調用的,均視為普通函數調用,此時this指向window對象

但是,在ECMAScript5的strict模式下,作為函數調用的 this被規定不會指向全局對象

 1 window.a = 2;
 2 var obj = {
 3     a:1,
 4     getA:function(){
 5         "use strict"
 6         console.log(this.a);
 7     }
 8 }
 9 var x = obj.getA;
10 x();   //underfined

作為構造函數調用

通常情況下,構造函數里的this指向返回的這個對象,但是如果構造器 顯示地返回了一個 object類型的對象,則this指向這個返回的object對象
 1 var Myclass = function(){
 2     this.name = 'beidan';
 3 }
 4 var obj = new Myclass();  
 5 console.log(obj.name);//beidan
 6  
 7 var Myclass = function(){
 8     this.name = 'beidan';
 9     return{         //顯示的返回一個對象,注意!既要是顯示,即有return,也要是對象{}
10         name:'test'
11     }
12 }
13 var obj = new Myclass();
14 console.log(obj.name);//test

作為function.prototype.call或function.prototype.apply調用

 

  • 理解call,apply

 

call,apply都是為了改變函數體內部 this 的指向。例如,fun1.call()或者fun1.apply() 都是為了改變fun1函數內部的this指向。

二者的作用完全一樣,只是接受參數的方式不太一樣。

func1.call(this,  arg1, arg2);        //參數列表arg1,arg2
func1.apply(this,  [arg1, arg2]);   //參數數組 [arg1,arg2]
 
第一個參數指定那個了 函數體內this對象的指向,他可以任何一個 JavaScript 對象(JavaScript 中一切皆對象),如果為null,則函數體內的this會指向默認的宿主對象,在瀏覽器中則是window。
 
第二個參數,call 需要把參數按順序傳遞進去,而 apply 則是把參數放在數組里。
當你的 參數不確定數量時用 apply ,然后把參數 push 進數組傳遞進去。或者也可以通過 arguments來獲取所有的參數。這樣看來,apply的使用率更高。
 
  • call,apply的用途

 

1.修正this的指向
比如,在實際開發中,會出現以下這種問題
1 document.getElementById('div1').onclick = function(){
2     console.log(this.id);   //div1
3     var func = function(){
4         console.log(this.id);    
5     }
6     func();   //通過普通函數調用,this指向window,輸出undefined
7 }
這時我們可以用call來修正 func 函數內this的指向。
1 document.getElementById('div1').onclick = function(){
2     console.log(this.id);   //div1
3     var func = function(){
4         console.log(this.id);
5     }
6     func.call(this);   //使用call,使func函數內部的this指向當前的函數對象,輸出div1
7 }

2.模擬繼承(借用其他對象的方法)

  • 例子一:其他對象(banana)借用apple中的say方法
1 function fruits() {}
2 fruits.prototype = {
3     color: "red",
4     say: function() {
5         console.log("My color is "+ this.color);
6     }
7 }
8 var apple = new fruits;
9 apple.say();    //My color is red
但是,如果我們還有其它 2個對象 banana= {color : "yellow"} ,orange = {color:‘orange’},想使用say方法,但是又不想對它們重新定義say方法。
那么,我們可以用apply或者call 借用 fruit里面的say方法
1 banana = {
2     color: "yellow"
3 };
4 orange = {color:‘orange’};
5 apple.say.call(banana);     //My color is yellow
6 apple.say.apply(orange );    //My color is orange
也就是說,當一個 object 沒有某個方法(本例子中banana沒有say方法),但是其他的有(本例子中apple有say方法),我們可以借助call或apply用其它對象的方法來操作。
再看幾個例子鞏固記憶
  • 例子二:獲取數組中的最大值和最小值
1 var numbers = [5, 458 , 120 , -215 ];
2 var maxInNumbers = Math.max.apply(Math, numbers),   //458
3     maxNumbers = Math.max.call(Math,5, 458 , 120 , -215, 666); //666
number 本身沒有 max 方法,但是 Math 有,我們就可以借助 call 或者 apply 使用其方法。

 

以上就是this在JavaScript中不同情況下的指向。

如果這篇文章對你有幫助,就給我一點贊賞吧~~~

 


免責聲明!

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



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