JavaScript OOP 之 this指向

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

咱們先來看一段代碼:java

你們能判斷出func();和obj.func();這兩句的this指向嗎?數組

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

可是,有幾點須要注意:this

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

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

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

 什麼是上下文context ?    對象

  常常看到不少資料文檔都有提到上下文,可是都不是太好理解。相信不少人犯迷糊。如今嘗試把本身的理解寫出來,也算是梳理一下。blog

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

  能夠想象一下語句執行前:有個上下文對象,名稱是 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會常常更新小技巧呢!若有不完善的地方,敬請拍磚!蟹蟹~~

相關文章
相關標籤/搜索