javascript中this用法例項詳解
JavaScript中的this含義非常豐富,它可以是全域性物件,當前物件或者是任意物件,這都取決於函式的呼叫方式。函式有以下幾種呼叫方式:作為物件方法呼叫、作為函式呼叫、作為建構函式呼叫、apply或call呼叫。
物件方法呼叫
作為物件方法呼叫的時候,this會被繫結到該物件。
1 2 3 4 5 6 7 8 9 |
this .y = this .y + y;
|
這裡我想強調一點內容,就是this是在函式執行的時候去獲取對應的值,而不是函式定義時。即使是物件方法呼叫,如果該方法的函式屬性以函式名的形式傳入別的作用域,也會改變this的指向。我舉一個例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
//3,this指向物件本身
|
這樣就明白了吧。這是一個容易混淆的地方。
函式呼叫
函式也可以直接被呼叫,這個時候this被繫結到了全域性物件。
1 2 3 4 5 6 |
|
但這樣就會出現一些問題,就是在函式內部定義的函式,其this也會指向全域性,而和我們希望的恰恰相反。程式碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
我們會發現不但我們希望的移動呢效果沒有完成,反而會多出兩個全域性變數。那麼如何解決呢?只要要進入函式中的函式時將this儲存到一個變數中,再運用該變數即可。程式碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
建構函式呼叫
在javascript中自己建立建構函式時可以利用this來指向新建立的物件上。這樣就可以避免函式中的this指向全域性了。
1 2 3 4 5 6 |
|
apply或call呼叫
這兩個方法可以切換函式執行的上下文環境,也就是改變this繫結的物件。apply和call比較類似,區別在於傳入引數時一個要求是陣列,一個要求是分開傳入。所以我們以apply為例:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
可以看到,正常訪問物件中方法時,this指向物件。使用了apply後,apply無引數時,this的當前物件是全域性,apply有引數時,this的當前物件就是該引數。
箭頭函式呼叫
這裡需要補充一點內容,就是在下一代javascript標準ES6中的箭頭函式的 this始終指向函式定義時的 this,而非執行時。我們通過一個例子來理解:
1 2 3 4 5 6 7 8 9 10 |
|
上面的程式碼會出現錯誤,因為this的指向從o變為了全域性。我們需要修改上面的程式碼如下:
1 2 3 4 5 6 7 8 9 10 11 |
|
通過使用外部事先儲存的this就行了。這裡就可以利用到箭頭函數了,我們剛才說過,箭頭函式的 this始終指向函式定義時的 this,而非執行時。所以我們將上面的程式碼修改如下:
1 2 3 4 5 6 7 8 |
|
這回this就指向o了,我們還需要注意一點的就是這個this是不會改變指向物件的,我們知道call和apply可以改變this的指向,但是在箭頭函式中是無效的。
1 2 3 4 5 6 7 |
|
這樣就可以明白各種情況下this繫結物件的區別了。