1. 程式人生 > >【JS檔案揭祕】第四集 關於this的討論到此為止

【JS檔案揭祕】第四集 關於this的討論到此為止

   網上關於this的指向問題的部落格文章很多,但大多數都是複製貼上,也不能用簡潔的語言講清楚,而是不停地寫一些示例,看得人云裡霧裡。

   其實關於this的指向並不難,只是沒有人去做一個好的總結和試驗,導致這個問題莫名其妙被複雜化了。

   這一集,我只給出結論,以及判定的通用方法,至於是否確實如我所講,大家可以自行驗證。

 

畫圖理解

  假設我們現在有一個函式foo,要判斷其中this的指向,可以根據下圖來分析:

  

 

   第一步,判斷函式是什麼型別:箭頭函式、普通函式還是繫結類函式(bind、call、apply);

   對於箭頭函式,需注意,首先箭頭函式其實是沒有 this 的,箭頭函式中的 this 只取決包裹箭頭函式的第一個普通函式的 this。如果往上級找一直沒找到包裹它的普通函式,那麼該箭頭函式中的this指向全域性物件。在瀏覽器中,全域性物件當然就是window;

    而對於繫結函式來說,this指向我們自定義的引數,在bind/call/apply中,即是第一個引數,第一個引數在瀏覽器環境中的預設值為window。這種情況屬於人為地改變this指向,順帶一提:如果對一個函式進行多次bind,只有第一次的bind是生效的,這屬於一個語法知識。

    

   第二步,對於普通函式來說,又分兩種情況:是被當作建構函式呼叫,還是被當作普通函式呼叫。

   如果是通過new關鍵字對其進行例項化,也就是把這個函式當作建構函式使用,那麼this恆指向例項化後的物件,此時的this是一個地址指標,指向例項化過程中在堆記憶體新開闢的用於儲存例項化物件的那一塊空間;

   如果是當作普通函式呼叫,那麼誰呼叫它,this就指向誰。有一種情況是類似於foo()這樣的呼叫,在瀏覽器中其實這相當於window.foo()。所以呼叫者為全域性物件window,this便指向window。

   

  當然,有時候會出現混合呼叫的情況,這時候就需要根據優先順序來決定,優先順序排名如下:

  建構函式(new)> 繫結函式(call/apply/bind)> 具體物件呼叫(obj.foo())> 全域性物件呼叫(foo())

&n