在平時的代碼中,相信你們常常用到 this
,但是你真的明白此 this
真的是你認爲的 this
嗎?今天柚子君總結了一下平時用到的 this
的場景,你們走過路過不要錯過啊~javascript
首先我們先來看一下《JavaScript 高級程序設計》上是怎麼說的。html
this
對象是在運行時基於函數的執行環境綁定的:在全局函數中,this
等於windows
,而當函數被做爲某個對象的方法調用時,this
等於那個對象。java
還有一種狀況,在《深刻理解 ES6》一書中寫道:git
若是箭頭函數被非箭頭函數包含,則
this
綁定的是最近一層非箭頭函數的this
,且不能經過call()
、apply()
或bind()
方法來改變this
的值。github
首先看一下非箭頭函數的狀況:windows
這是一個普通的函數聲明,在這種狀況下,this
是指向 window
的.瀏覽器
var test = '哈哈哈';
function thisHandler() {
console.log('test:',this.test,'this:',this);
}
thisHandler() // test: 哈哈哈 this: window複製代碼
其實上面的代碼就至關於 window
調用 thisHandler()
,因此這時 this
指向 window
:bash
var b = '哈哈哈';
function thisHandler() {
console.log('b:',this.b,'this:',this);
}
window.thisHandler() // b: 哈哈哈 this: window複製代碼
看成爲對象的方法被調用時,this
這時就指向調用它的對象。網絡
var thisHandler = {
name: "柚子",
test: function(){
console.log('my name:',this.name);
}
}
thisHandler.test() // my name: 柚子複製代碼
再來一個栗子🌰:app
var thisHandler = {
name: "柚子",
fn: {
name: '芒果',
test: function() {
console.log('my name:',this.name);
}
}
}
thisHandler.fn.test() // my name: 芒果複製代碼
這時 this
指向的是對象 fn
了,因此,關於對象調用這一點明白了嗎,若是明白了,那不要緊,接着看下一個強化題😏:
var name = '柚子'
var thisHandler = {
name: "芒果",
fn: {
name: '糖果',
test: function(){
console.log('my name:',this.name);
}
}
}
var testHandler = thisHandler.fn.test
testHandler()複製代碼
🍭 這裏是一秒鐘分割線 🍭
噠噠噠,答對了,這裏的 this
指向的 window
,那麼這是爲何呢,哪位小盆友來回答一下。
舉手:
上面說到了,
this
指向的是最後調用它的對象,第一步是賦值給了testHandler
,最後執行的那一句至關於window.testHandler()
。因此這裏的this
指向的是window
。最後輸出的就是my name: 柚子
。
噠噠噠,真聰明,來闖下一關~
var name = '柚子'
function Bar() {
this.name = '芒果'
}
var handlerA = new Bar();
console.log(handlerA.name); // 芒果
console.log(name) // 柚子複製代碼
其實要明白爲何會是這樣一個結果,我們就要來聊聊 new
作了哪些事情。
__proto__
屬性設置爲 Bar.prototype
。Bar
被傳入參數並調用,關鍵字 this
被設定爲該實例。弄明白了 new
的工做內容,天然而然的也明白了上面輸出的緣由。
Bar()
中的this
指向對象handlerA
,並非全局對象。
關於 apply
,能夠看一下 MDN 關於 apply()
方法的說明。
使用 apply
方法能夠改變 this
的指向。若是這個函數處於非嚴格模式下,則指定爲 null 或 undefined 時會自動指向全局對象(瀏覽器中就是window對象)。
var name = '芒果';
var thisHandler = {
name: "柚子",
test: function(){
console.log('my name:',this.name);
}
};
thisHandler.test(); // my name: 柚子
thisHandler.test.apply(); // my name: 芒果複製代碼
下面是箭頭函數的舞臺~
在《深刻理解 ES6》一書中能夠知道箭頭函數和普通函數的一個不一樣之處就在於 this
的綁定。
箭頭函數中沒有
this
綁定,必須經過查找做用域鏈來決定其值。若是箭頭函數被非箭頭函數包含,則this
綁定的是最近一層非箭頭函數的this
;不然,this
的值會被設置爲undefined
。
var name = '柚子'
var thisHandler = {
name: '芒果',
test:() => {
console.log('my name:',this.name,'this:',this);
}
}
thisHandler.test(); // my name: 柚子 this: Window複製代碼
這時 this
不是指向 thisHandler
,而是 Window
。
關於 this
的使用和體會仍是要在平時運用中理解,先了解其原理,那麼在使用的時候就如魚得水啦。