作用域就是變量和函數的可訪問范圍,控制著變量和函數的可見性與生命周期,在JavaScript中變量的作用域有全局作用域和局部作用域。
全局和局部作用域下面用1張圖來解釋:
單純的JavaScript作用域還是很好理解的。
全局履行環境是最外層的1個履行環境,在web閱讀器中全局履行環境是window對象,因此所有全局變量和函數都是作為window對象的屬性和放大創建的。每一個函數都有自己的履行環境,當履行流進入1個函數的時候,函數的環境會被推入1個函數棧中,而在函數履行終了后履行環境出棧并被燒毀,保存在其中的所有變量和函數定義隨之燒毀,控制權返回到之前的履行環境中,全局的履行環境在利用程序退出(閱讀器關閉)才會被燒毀。
當代碼在1個環境中履行時,會創建變量對象的1個作用域鏈(scope chain)來保證對履行環境有權訪問的變量和函數的有序訪問。
用1張圖來解釋作用域鏈的運行:由里向外履行。
當1個函數創建后,它的作用域鏈會被創建此函數的作用域中可訪問的數據對象填充,例如定義下面這樣1個函數:
函數add的作用域將會在履行時候用到,例如履行以下代碼:
這些值依照它們出現在函數中的順序被復制到運行期上下文的作用域鏈中。它們共同組成了1個新的對象,叫“活動對象(activation object)”,該對象包括了函數的所有局部變量、命名參數、參數集合和this,然后此對象會被推入作用域鏈的前端,當運行期上下文被燒毀,活動對象也隨之燒毀。新的作用域鏈以下圖所示:
在函數履行進程中,沒遇到1個變量,都會經歷1次標識符解析進程以決定從哪里獲得和存儲數據。該進程從作用域鏈頭部,也就是從活動對象開始搜索,查找同名的標識符,如果找到了就使用這個標識符對應的變量,如果沒找到繼續搜索作用域鏈中的下1個對象,如果搜索完所有對象都未找到,則認為該標識符未定義。
根據上述講的作用域鏈的結構可以看出,定義的標識符的越深,那末讀寫的速度也就越慢,而全局變量總是處于作用域鏈的最末端,所以當變量解析的時候,查找全局變量是最慢的,所以在編寫代碼的時候要盡量少的使用全局變量,盡量使用局部變量。
上一篇 軟考之進程,線程,管程比較