以下轉載自:鏈接:https://www.jianshu.com/p/c1ee12a328d2/
一,瞭解前須知
1,箭頭函數:出現的作用除了讓函數的書寫變得很簡潔,可讀性很好外;最大的優點是解決了this執行環境所造成的一些問題。比如:解決了匿名函數this指向的問題(匿名函數的執行環境具有全局性),包括setTimeout和setInterval中使用this所造成的問題。
2,我們常見的window屬性和方法有alter,document,parseInt,setTimeout,setInterval,localtion等等,這些在默認的情況下是省略了window前綴的。(window.alter = alter)。
3,在“use strict”嚴格模式下,沒有直接的掛載者(或稱調用者)的函數中this是指向window,這是約定俗成的。在“use strict”嚴格模式下,沒有直接的掛載者的話,this默認爲undefined。以下都是在非嚴格模式下討論。
二,普通函數中的this
普通函數,this的概念是:this是JavaScript的一個關鍵字,他是指函數執行過程中,自動生成的一個內部對象,是指當前的對象,只在當前函數內部使用。(this對象是在運行時基於函數的執行環境綁定的:在全局函數中,this指向的是window;當函數被作爲某個對象的方法調用時,this就等於那個對象)。
一個最簡單的例子:
這種情況下,我們希望在每一次循環後都能得到$("#content")的this,但是因爲this是隻在當前函數內部使用的,又因爲js函數是可以多層嵌套的原因,使得我們無法得到最開始的this,這時我們可以把他先用一個變量存儲起來,最終達到我們想要的目的。(一般我們會這樣定義:var _this = this var that=this)。個人習慣是用後者。
我們在來看一個函數的例子:
打印是結果是the window。原因是,匿名函數的執行環境是全局的,而且this只在函數內部起作用。此時的this.name在匿名函數中找不到,所以就從全局中找,找到後打印出來。
我們將上面的函數改裝一下:
我們在getNameFun內將this賦給that,此時的that指向的是掛載(調用)的對象,即爲object,此時在匿名函數中調用that.name會在object上查找相應的數據,而不是在全局上查找,最終打印出myobject。
我們試着把函數的執行對象放在window下看看:
打印的結果是window的對象,如下圖:
接下來我們把函數的執行對象放在一個自定義變量上看看:
兩者打印的都是obj的對象,如下圖:此時的setTimeout裏面的that指向的是obj,因爲在say中this的綁定對象是obj,this又賦給了that。
下面爲了更深一步的理解this這個概念,我們來看一下下面的代碼,並判斷其運行結果:
這個函數中,obj.db1()執行時,this.val是指obj裏面的val=2,this.val*=2 =4;val在db1函數中並沒有定義,所以默認情況下會在全局上找,此時val*=2=2。所以打印2 4。接着,定義一個func=obj.db1,我們把func打印出來看看是這樣的:
所以可以看出func的執行對象是window,我們可以此時全局的val已經等於4了,在經過this.val*=2,val*=2的運算,打印的結果就是8 8。
上面的代碼打印的就是:
如果你對上面的結果很瞭解了,那就證明你已經很瞭解this,那接下來我們來看看es6箭頭函數的this
三,es6箭頭函數的this
箭頭函數的this定義:箭頭函數的this是在定義函數時綁定的,不是在執行過程中綁定的。簡單的說,函數在定義時,this就繼承了定義函數的對象。
所以,這會很好的解決匿名函數和setTimeout和setInterval的this指向問題。我們不用再去給其用that變量存儲this。
看下面代碼:
打印的結果:
這就是箭頭函數中的this!!!