Javascript中老生常談的this用法,你掌握了嗎?
在物件導向語言如Java,C++中,this指向的永遠是當前物件,這個很好理解,通過new方法生成的任意一個物件,this都指向new出來的物件本身。
但是在Javascript中,由於語言設計的靈活性,this的指向是會隨時變化的,
Javascript中的this
方法調用模式當一個物件中包含的某個屬性為一個函數時,在該函數中this指向的是該物件嗎,通過以下代碼可以更明確的瞭解。
方法調用模式
構造器類似於物件導向語言的構造方法,通過new方法,傳入相應的參數後便可生成一個新的物件,this會指向這個新生成的實例。
構造器調用模式
在上述例子中,通過將methodCall的prototype屬性指向一個新的物件,所有new出來的新物件都具有printVal方法,
而在這個物件中使用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方法,會改變方法的實際執行實體,
apply/call模式
我們來分析下上面的例子。
首先通過new方法生成一個新的methodCall實例,然後調用printStr方法,相當於構造器調用模式,會列印出inner。
然後通過call方法傳遞物件a自己,言外之意並未改變函數執行的實體,因此也會列印出inner。
第三句如果直接調用printStr方法,
第四句直接列印,相當於在window上執行,會輸出outer。
第五句通過給call方法傳遞window,言外之意並沒有改變函數執行體,因此會輸出outer。
第六句原來是執行的a.printStr方法,但是通過call方法改變了函數執行實體,最終會在window上執行,因此會輸出outer。
結束語this的使用在Javascript中,存在很多的坑,但是只要理解原理性的東西,還是很好掌握的,希望大家平時多做總結。