本文來自 @position_柚子,地址:https://juejin.im/post/5995c7a76fb9a0247a60c407javascript
在平時的代碼中,相信你們常常用到 this
,但是你真的明白此 this
真的是你認爲的 this
嗎?今天柚子君總結了一下平時用到的 this
的場景,你們走過路過不要錯過啊~java
首先我們先來看一下《JavaScript 高級程序設計》上是怎麼說的。windows
this
對象是在運行時基於函數的執行環境綁定的:在全局函數中,this
等於 windows
,而當函數被做爲某個對象的方法調用時,this
等於那個對象。瀏覽器
還有一種狀況,在《深刻理解 ES6》一書中寫道:app
若是箭頭函數被非箭頭函數包含,則 this
綁定的是最近一層非箭頭函數的 this
,且不能經過 call()、apply() 或 bind()
方法來改變 this 的值。函數
首先看一下非箭頭函數的狀況:post
這是一個普通的函數聲明,在這種狀況下,this
是指向 window
的:this
var test = '哈哈哈'; function thisHandler() { console.log('test:',this.test,'this:',this); } thisHandler() // test: 哈哈哈 this: window
其實上面的代碼就至關於 window
調用 thisHandler()
,因此這時 this
指向 window
prototype
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: 柚子
再來一個栗子:
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
方法能夠改變 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
的使用和體會仍是要在平時運用中理解,先了解其原理,那麼在使用的時候就如魚得水啦。