華文網

Javascript中老生常談的this用法,你掌握了嗎?

this指的是什麼?

在物件導向語言如Java,C++中,this指向的永遠是當前物件,這個很好理解,通過new方法生成的任意一個物件,this都指向new出來的物件本身。

但是在Javascript中,由於語言設計的靈活性,this的指向是會隨時變化的,

但是也要記住一句話,this永遠指向的是函數的調用者。接下裡我們再具體看看this指向所分的幾種情況。

Javascript中的this

方法調用模式

當一個物件中包含的某個屬性為一個函數時,在該函數中this指向的是該物件嗎,通過以下代碼可以更明確的瞭解。


方法調用模式

構造器調用模式

構造器類似於物件導向語言的構造方法,通過new方法,傳入相應的參數後便可生成一個新的物件,this會指向這個新生成的實例。

構造器調用模式

在上述例子中,通過將methodCall的prototype屬性指向一個新的物件,所有new出來的新物件都具有printVal方法,

同時在構造器中通過this添加了一個val屬性,代表這是一個成員變數,每個新實例都具有val屬性。

而在這個物件中使用this,則this會指向新生成的實例,因此最後會返回inner。

函式呼叫模式

當一個函數並未綁定至任何物件上而直接進行調用時,會脫離所在的函數體,此時this會指向全域物件。

函式呼叫模式

在上述的例子中,通過調用innerPrintStr方法來列印出this和that指向的str變數。

在printStr方法中,首先將this用that變數保存,指向是新生成的methodCall實例,相當於構造器調用模式,因此會先輸出inner值。

然後是直接調用this.str,因為innerPrintStr方法並未綁定在任何函數上,相當於一個全域的函數,因此this會指向window,而在window上定義了str為outer,因此會後輸出outer值。

apply/call模式

我們都知道,通過執行apply/call方法,會改變方法的實際執行實體,

this也要隨著實體變化而變化。

apply/call模式

我們來分析下上面的例子。

首先通過new方法生成一個新的methodCall實例,然後調用printStr方法,相當於構造器調用模式,會列印出inner。

然後通過call方法傳遞物件a自己,言外之意並未改變函數執行的實體,因此也會列印出inner。

第三句如果直接調用printStr方法,

會列印出outer,但是因為通過call方法,改變了方法的執行體,最終是在a上執行,因此會列印出inner。

第四句直接列印,相當於在window上執行,會輸出outer。

第五句通過給call方法傳遞window,言外之意並沒有改變函數執行體,因此會輸出outer。

第六句原來是執行的a.printStr方法,但是通過call方法改變了函數執行實體,最終會在window上執行,因此會輸出outer。

結束語

this的使用在Javascript中,存在很多的坑,但是只要理解原理性的東西,還是很好掌握的,希望大家平時多做總結。

還是很好掌握的,希望大家平時多做總結。