JavaScript中this指向問題
記得初學 JavaScript 時,其中 this
的指向問題曾讓我頭疼不已,我還曾私自將其與閉包、原型(原型鏈)並稱 JS 武林中的三大魔頭。若是你要想在 JS 武林中稱霸一方,必須將這三大魔頭擊倒。我的認爲在這三大魔頭中,this
指向問題的武功最菜(難度最低)。俗話說柿子撿軟的捏,那咱們就先從 this
指向問題下手。javascript
先記住攻克 this
指向問題的口訣(前輩們的總結):哪一個對象調用函數,函數裏的 this
就默認指向哪一個對象(注意 this
只能指向對象)。這裏說「默認指向」是由於咱們經過箭頭函數、call、apply、bind等手段來改變 this
的指向。如今咱們只討論 this
的默認指向。java
全局做用域下以及全局做用域的函數中,this默認指向全局對象window
在嚴格模式下,全局做用域的函數中,this默認指向 undefined, 這是嚴格模式所規定的。閉包
// 非嚴格模式下 console.log(this); // Window function doSomething(){ console.log(this); // Window } doSomething(); // 這裏能夠當作window.doSomething(),因此函數裏的this指向全局對象window // 嚴格模式下 'use strict'; console.log(this); // Window function doInStrict(){ console.log(this); // undefined } doInStrict();
對象裏的函數,this指向該對象
var a = 1; var obj = { a: 2, fn: function(){ console.log(this); // {a: 2, fn: ƒ} console.log(this.a); // 2 } }; obj.fn();
上面函數被調用後,從打印結果能夠看出此時 this
指向的是調用函數的對象 obj。若是將對象中的函數賦給全局對象中定義的變量 fn1,執行 fn1 又會出現什麼結果呢?app
var a = 1; var obj = { a: 2, fn: function(){ console.log(this); // Winidow console.log(this.a); // 1 } }; var fn1 = obj.fn; fn1(); // 能夠當作window.fn1();
從上面的例子能夠看出,fn1 與 obj.fn 指向的函數是相同的,可是調用它的對象不一樣,那麼函數中 this
的指向也就不同了。函數
再看一個比較複雜的例子:this
var a = 0; function fn(){ consoloe.log(this.a); } var obj1 = { a: 1, fn: function(){ console.log(this.a); } }; var obj2 = { a: 2, fn: function(){ fn(); obj1.fn(); console.log(this.a); } } obj2.fn();
先說下執行結果,分別打印 0 1 2
。當 obj2 調用 fn 函數時,先執行的是 fn()
,這個函數是在全局做用域中定義的,該調用能夠當作 window.fn()
,因此,該函數內部的 this
指向的是 window 全局對象,this.a
天然就是全局對象中的 a 值(0)。spa
接着執行的是 obj1.fn()
,它會從 obj1 中找到 fn 函數並執行。obj1 中的函數 fn 執行時調用它的對象是 obj1,因此,此時函數內部的 this
指向的就是 obj1 自身。那麼 this.a
查到的值也就是對象 obj1 中 a 的值(1)。code
最後打印函數中 this
所處的函數 fn 是被 obj2 調用的,那麼天然而然 this
就指向了 obj2,因此 this.a
的結果就是 2 了。對象
從上面這個例子咱們能夠看出:函數內部 this 指向跟調用函數的對象有關,跟函數在哪裏調用沒有關係。ip
Window內置函數的回調函數中,this指向Window對象。
window 的內置函數( setInterval setTimeout 等),其回調函數中的 this
指向的是window對象。
var name = 'window'; var obj = { name: 'obj', func: function(){ setTimeout(function () { console.log(this.name) // window },1000) } } obj.func()
可是通常在開發中,不少場景都須要改變 this
的指向。 後面我會專門寫一篇關於更改 this
指向的文章,這裏就再也不贅述了。