今天給你們分享一個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會常常更新小技巧呢!若有不完善的地方,敬請拍磚!蟹蟹~~