什麼是「執行上下文」(也叫作「執行上下文環境」)?暫且不下定義,先看一段代碼:javascript
第一句報錯,a未定義,很正常。第二句、第三句輸出都是undefined,說明瀏覽器在執行console.log(a)時,已經知道了a是undefined,但殊不知道a是10(第三句中)。html
在一段js代碼拿過來真正一句一句運行以前,瀏覽器已經作了一些「準備工做」,其中就包括對變量的聲明,而不是賦值。變量賦值是在賦值語句執行的時候進行的。可用下圖模擬:前端
這是第一種狀況。java
下面還有。先來個簡單的。web
有js開發經驗的朋友應該都知道,你不管在哪一個位置獲取this,都是有值的。至於this的取值狀況,比較複雜,會專門拿出一篇文章來說解。面試
與第一種狀況不一樣的是:第一種狀況只是對變量進行聲明(並無賦值),而此種狀況直接給this賦值。這也是「準備工做」狀況要作的事情之一。json
下面還有。。。第三種狀況。瀏覽器
在第三種狀況中,須要注意代碼註釋中的兩個名詞——「函數表達式」和「函數聲明」。雖然二者都很經常使用,可是這二者在「準備工做」時,倒是兩種待遇。閉包
看以上代碼。「函數聲明」時咱們看到了第二種狀況的影子,而「函數表達式」時咱們看到了第一種狀況的影子。app
沒錯。在「準備工做」中,對待函數表達式就像對待「 var a = 10 」這樣的變量同樣,只是聲明。而對待函數聲明時,卻把函數整個賦值了。
好了,「準備工做」介紹完畢。
咱們總結一下,在「準備工做」中完成了哪些工做:
這三種數據的準備狀況咱們稱之爲「執行上下文」或者「執行上下文環境」。
這裏插一句題外話:經過以上三種狀況,你可能會聯想到網上的有些考js語法的題目/面試題。的確,幾乎每一個js語法題中都有這種題目出現。以前你遇到這種題目是否是靠背誦來解決?背過了,隔幾天又忘記了。——任何問題,都要去追根溯源,要知道這個問題是真正出自哪一塊知識點,要真正去理解。光靠背誦是沒用的。
細心的朋友可能會發現,咱們上面全部的例子都是在全局環境下執行的。
其實,javascript在執行一個代碼段以前,都會進行這些「準備工做」來生成執行上下文。這個「代碼段」其實分三種狀況——全局代碼,函數體,eval代碼。
這裏解釋一下爲何代碼段分爲這三種。
所謂「代碼段」就是一段文本形式的代碼。
首先,全局代碼是一種,這個應該沒有非議,原本就是手寫文本到<script>標籤裏面的。
其次,eval代碼接收的也是一段文本形式的代碼。
最後,函數體是代碼段是由於函數在建立時,本質上是 new Function(…) 得來的,其中須要傳入一個文本形式的參數做爲函數體。
這樣解釋應該能理解了。
最後,eval不經常使用,也不推薦你們用。
下一節咱們介紹函數的狀況,並一塊兒總結一下執行上下文到底包含哪些內容。敬請期待。
---------------------------------------------------------------------------
本文已更新到《深刻理解javascript原型和閉包系列》的目錄,更多內容可參見《深刻理解javascript原型和閉包系列》。
另外,歡迎關注個人微博。
學習做者教程:《前端JS高級面試》《前端JS基礎面試題》《React.js模擬大衆點評webapp》《zepto設計與源碼分析》《json2.js源碼解讀》