JavaScript OOP 之 this指向


今天給大家分享一個JavaScript OOP中關於分辨this指向對象的小技巧,很實用呦!

我們先來看一段代碼:

大家能判斷出func();和obj.func();這兩句的this指向嗎?

首先,我們都知道的是,this的指向就是最終調用函數的對象。可是最終調用函數的對象,你能清楚地判斷出來嗎?

但是,有幾點需要注意:

  ① this 指向誰,不應該考慮函數在哪聲明,而應該考慮函數在哪調用!

  ② this 指向的永遠只可能對象,而不可能是函數。

  ③ this 指向的對象 ,叫做函數的上下文context,也叫函數的調用者。 

 什么是上下文context ?    

  經常看到很多資料文檔都有提到上下文,但是都不是太好理解。相信很多人犯迷糊。現在嘗試把自己的理解寫出來,也算是梳理一下。

  上下文 —— 我把它理解為當前運行環境,程序運行時,程序的每條語句都有對應的上下文,即運行環境。

  可以想象一下語句執行前:有個上下文對象,名稱是 context,上下文對象是window對象,即: context = window。

  直接調用函數func(),此時函數體內的上下文對象就是window。

  對象obj調用func函數,即:obj.func()  時,函數體內的上下文對象就是window.obj對象。

  this的值,就是運行到this代碼位置時,上下文所對應的上下文對象。函數定義是並沒有運行console.log(this)語句,所以函數定義是this指向的對象還未定義,它的值是undefined,需要在函數調用時,邊解釋邊執行,執行 console.log(this) 時才分析調用函數是的上下文。最終確定this指向的值。

下面我們來看一下更多的情況,總結一下更多的規律,讓大家面對this不再糊塗:

【 接下來,我們詳細解讀一下 】

① 通過 函數名() 調用的,this永遠指向window。就是上述例子的第一個調用 func();

結果(window)

 

② 通過 對象.方法 調用的,this指向這個對象。就是上述例子的第二種調用方式 obj.func();

 

 結果(obj)

 

③ 函數 作為數組中的一個元素存在,用數組下標調用,this指向這個數組。

 結果(數組arr)

 

④ 函數作為 window 內置函數的回調函數使用,this指向window 。

結果(window)

 

⑤ 函數作為構造函數,使用new關鍵字調用,this指向新new出的對象。

 

結果(objs)

【區分】在HTML中新增一個div,給div添加點擊事件。

<div id="div1" style="width: 200px;height: 200px;background-color: red;" onclick="func(this)">
     這是一個div
</div>

<script type="text/javascript">
        window.onclick = function(){
                 document.getElementById("div1").onclick = function(){  
                 func();   //  最終還是使用()調用,指向Window
            }                            
                 document.getElementById("div1").onclick = func;   // 廣義對象  通過對象.方法 調用的,this指向這個對象                
            }          
    function func(){
        console.log(this);
    }
</script>                    

 

規律咱們總結完了,接下來來兩個題目練練手吧!

 first one:

function func(){
    console.log(this);
            }
 var obj1 = {
     name : "obj1",
     arr : [func,1,{name:"obj2",func:func},3,setTimeout(func,1000)],
}           
// 通過對象取到數組,然后通過數組的下標調用該函數,最終指向數組。this -> obj.arr obj1.arr[0]();                    // obj1.arr[0]:目的是取到func,給setTimeout作為回調函數,相當於setTimeout(func,2000)。this -> window setTimeout(obj1.arr[0],2000); obj1.arr[2].func();    // 最終調用者{name:"obj2",func:func} 屬於②情況 setTimeout(obj1.arr[2].func,2000);   // 最終調用者是setTimeout,同上

結果如下顯示:(調用了三次延時函數,包括一次自動調用)

 

second one:

    var fullname = 'John Doe';
        var obj = {
           fullname: 'Colin Ihrig',
           prop: {
              fullname: 'Aurelio De Rosa',
              getFullname: function() {
                 return this.fullname;
              }
           }
        };
        console.log(obj.prop.getFullname());  // 函數的最終調用者 obj.prop 
        
        var test = obj.prop.getFullname; 
        console.log(test());       // 函數的最終調用者 test()  this-> window
        
        obj.func = obj.prop.getFullname;  // 給obj追加方法
        console.log(obj.func());     // 函數最終調用者是obj
        
        var arr = [obj.prop.getFullname,1,2];
        arr.fullname = "TraceyW";
        console.log(arr[0]());     // 函數最終調用者數組        
            

結果如下顯示:

 

總結一下,this指向的規律,大家可以發現,這個規律跟函數的調用方式息息相關:

  ① 通過 函數名() 調用的,this永遠指向window。

  ② 通過 對象.方法 調用的,this指向這個對象。

  ③ 函數 作為數組中的一個元素存在,用數組下標調用,this指向這個數組。

  ④ 函數作為 Window 內置函數的回調函數使用,this指向window。  如setInterval 、 setTimeout ...

  ⑤ 函數作為構造函數,使用new關鍵字調用,this指向新new出的對象。

挺有用的,拿走不謝!

有需要的點關注呦~~小W會經常更新小技巧呢!如有不完善的地方,敬請拍磚!蟹蟹~~

 


免責聲明!

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



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