本文是參照高程(JavaScript 高級程序設計)加上一些我的的理解和總結,使用簡單的小例子和一些代碼片斷來儘可能解釋清楚做用域和做用域鏈。(本文適用於具有一些JS基礎的朋友拿來參考)html
執行環境定義了變量或者函數有訪問其餘數據的權限 。在 JavaScript 中,有一個最外層的全局執行環境,在Web瀏覽器中,一般咱們認爲就是window這個對象。
經過一個小例子來解釋一下在定義函數和執行函數分別發生了哪些事情。 從這張圖中,咱們能看出,當咱們定義了一個函數 test1 時,
一、首先在堆內存中建立了一個Function對象,而後將地址存在 test1 中;
二、自動建立一個對象,而且該對象有一個 constructor 屬性指向該函數自己,最後該函數對象的prototype屬性指向這個對象;
三、將包括全局對象在內的,在函數執行過程當中建立的活動對象(後文解釋)都存在該函數自身的內部屬性[[Scope]]上。瀏覽器
當執行一個函數(test1)時,
一、首先會建立一個執行環境ECS及相應的做用域鏈;
二、而後使用arguments和函數的參數(若是有)的值來初始化函數的活動對象(Active Object)也就是上面所說的活動對象;
其中,該函數對應的做用域鏈是經過取出[[Scope]]的值,而且將當前函數的活動對象推入做用域鏈的最頂層。閉包
以上咱們簡單的說了一下函數定義和執行,這樣有助於咱們理解做用域鏈以及我博客中的 閉包 和 以及 如何解釋let在for循環中的特殊表現。函數