面試官:能解釋一下javascript中的this嗎

一.前言

  關於javascript中的this對象,可能已經被你們說爛了。javascript

  即便是這樣,我依然決定將這篇文章給水出來。畢竟全國在新型肺炎的影響下,公司無法正常復工。java

  除了刷刷手機,仍是要適當的學習一下。面試

  廢柴是真很差當,勞逸結合纔是王道。函數

二.正戲開始

  面試官:你能給我解釋一下javascript中的this嗎學習

  我:(固然能夠哇,成竹在胸,咳咳)javascript中的this對象是指函數運行時,在函數內部生成的一個對象。測試

  面試官:那你大概說一下它的用法吧this

  我:(摩拳擦掌準備開始吹水)好,我大概說幾種使用場景。(接下來就須要我一我的演戲了)spa

  

  第一種是全局函數中的this對象。3d

  好比下面這個全局函數testcode

<script>
  function test(){        } </script>

  假如咱們將這個全局函數做爲普通函數使用,那麼這個全局函數內部的this對象指向的就是window對象。

  

   (事實勝於雄辯,雖然不能給面試官看結果,可是氣勢上已經拿到一分)

  除了做爲普通函數使用以外,test全局函數也能夠做爲構造函數去使用,那麼函數內部的this對象指向的是構造函數建立出來的實例

  

  在test構造函數中,this.a=10這行是關鍵代碼。

  假設咱們在不知道this對象是什麼的狀況下,這行代碼僅僅是給this對象添加了一個屬性a,而且賦值爲10 。

  而後看測試結果打印出來的對象o,發現o也多了一個屬性a,它的值也爲10 。

  因此不難想到在test函數運行時,this綁定到了new出來的對象上,即this指向了構造函數建立出來的實例o;

  第一種this的使用場景就吹完了,若是這樣囉嗦的回答面試官,估計就直接讓我回家了。

  因此總結一下我這樣回答面試官:

    第一種全局函數中的this對象,假如咱們將這個全局函數做爲普通函數使用,那麼這個全局函數內部的this對象指向的就是window對象;

    若是將這個全局函數做爲構造函數使用,那麼函數內部的this對象指向的是構造函數建立出來的實例。

 

  第二種是對象方法中的this。

  在好比下面這個obj對象的increase方法。

var obj = {
  a: 10,
  increase: function(){
	this.a++;
  }
}

  如今咱們去調用obj對象的increase方法

  

  obj的increase方法中的關鍵代碼爲this.a++,該函數調用完成後,在去打印obj對象,發現obj對象中a的屬性值由10增長爲11。

  那麼increase方法這中的this.a++的效果實際上等效於obj.a++。

  因此對於第二種對象方法中的this,它指向的就是該對象自己。

  

  那麼到這裏,我已經個人能力範圍內回答完了面試官的問題。

  (若是幸運的話,面試官應該還不會趕我走)

 

  面試官:說了這麼多,那我這裏有幾個實例代碼,你來給我分別說一下這幾個示例代碼輸出都是什麼吧。

  (接着面試官扔給我幾張寫滿了代碼的A4紙)。

  我:(忽然心慌慌,可是不能慫,按照前面說的幾種場景往裏套唄)

  題目一:

  

  (看到這個心情愉快呀,這不就是我剛說的this的第一種使用場景嗎。並且是將全局函數做爲普通函數使用,那函數裏的this指向的就是window。那既然函數f中的this指向的是window對象,那this.age就至關於window.age。而後我鎮定自若的回答面試官)

  題目一按照代碼執行的輸出順序,第4行的輸出結果爲20,第7行的輸出結果也是20(面試官不說話,應該是默認了個人回答是正確的)。

 

  題目二:

  

 

   (這個乍一看跟題目一有些類似,只是在第3行中對age的定義有了變化,並且在第6行還多了一個打印輸出。

   在往下看,發現函數f依然是做爲普通函數去使用的,那既然是這樣,第3行的this.age=40也就至關於window.age=40。

   因此第3行代碼執行的時候確定會覆蓋第1行對age的賦值。到這裏我微微一笑,開始回答面試官)

     題目二按照代碼執行的輸出順序,第6行輸出結果爲20;第4行當輸出結果爲40;第8行當輸出結果爲40。

  

  題目三:

  

  (這個題目一看仍是我前面說的this的第一種使用場景,只是全局函數做爲普通函數使用)

  題目三按照代碼執行的輸出順序,第5行輸出20;第8行輸出20。

  

  題目四:

  

  (額,這個代碼有點長呀,可是不能慌。

    看完前8行以爲沒啥問題,第九、10行看完後內心咯噔了一下。

    將obj的getName方法賦值給了一個變量fn,而後打印fn()???

    靜下心想想,第9行其實是以聲明式方式建立了一個全局函數fn,而後在第10行調用fn。

   接着我陷入了沉思,那調用fn時,這個this究竟是指向obj對象呢,仍是指向全局的window對象。

   大腦飛速旋轉,想到剛開始對面試官說的那句話:javascript中的this對象是函數運行時,在函數內部生成的一個對象。

   因而我不斷的重複這句話,而後一個激靈反應上來,既然是this是函數運行時生成的,那我應該關注fn函數運行時的狀況呀。

   先拋開函數fn是由obj的getName方法賦值生成的這個事情。

   fn生成之後,它是一個全局函數,這個毋庸置疑。再者,fn運行時是以普通函數的方式調用的。

  那fn函數在運行時,內部的this對象就是window了,那第10行打印就是全局的"babi"了,恩,必定是這樣。

     擦擦汗在繼續看,又發現了16行的代碼,感受和第10行代碼有些殊途同歸之處。

  接着前面的思路往裏套,無論otherObj.getName是怎麼建立的,它在運行的時候是做爲otherObj對象的方法運行的,那這就符合前面說的第二種使用this的場景:對象方法中的this,它指向的就是該對象自己。

  想完這些擡頭看了一下面試官,一聲不響甚至有些不耐煩,因而虛虛的回答他)

 

  題目四按照代碼執行的輸出順序,第10 行的輸出結果爲"babi";第17行的輸出結果爲"mini"。

  (此時看到面試官眉頭舒展,微微一笑)

 

  面試官:好,那這個問題到此結束......

 

三.拷問結束

  面試官的靈魂拷問結束後,回到家裏把記得的示例代碼都驗證了一遍,居然發現都對了。

  因而默默的獎勵本身一個雞腿。

  

 

  聲明:文章中場景純屬捏造,切勿當真。小小總結,歡迎拍磚。

相關文章
相關標籤/搜索