執行環境
所有變量(基本類型、引用類型以及函數)都存在於一個執行環境當中,這個執行環境決定了變量的生命周期,以及哪一部分代碼可以訪問其中的變量。
每個執行環境都有一個與之關聯的變量對象,環境中定義的所有變量和函數都保存在這個對象中。
執行環境可以划分為兩類:
-
全局執行環境
全局執行環境是最外圍的一個執行環境。根據ECMAScript實現所在的宿主環境不同,表示執行環境的變量對象也不一樣。例如,在WEB瀏覽器中,與全局執行環境關聯的變量對象是
windows
對象。 -
函數執行環境
每個函數都有自己的執行環境,函數執行環境的變量對象被稱為活動對象,它在最開始只包含一個變量,即
arguments
對象。
作用域鏈
執行流每進入一個執行環境,都會創建一個作用域鏈。
作用域鏈由執行環境的變量對象組成,作用域鏈的前端始終是當前執行環境的變量對象,下個變量對象來自外圍環境,再下一個變量對象則來自下一個外圍環境,一直延續到全局執行環境的變量對象。全局執行環境的變量對象始終都是作用域鏈中的最后一個變量對象。
作用域鏈的用途是保證對執行環境有權訪問的所有變量和函數的有序訪問。
延長作用域鏈
當執行流進入try - catch
語句的catch
塊或者進入with
語句,解釋器就會再當前作用域鏈的最前端增加一個變量對象。這個變量對象是臨時的,它會在語句執行完后被移除。
延長作用域鏈的特點是:
- 添加的變量對象是臨時的,在語句執行完后將被移除
- 添加的變量對象不關聯執行環境。這意味着在語句中聲明的變量屬於包含這些特殊語句的執行環境的變量對象。
var location = new Object();
location.href = "https://baidu.com/";
function buildUrl() {
var qs = "search?wd=%s";
with (location) {
var url = href + qs;
}
alert(url);
}
buildUrl();
全局執行環境中定義了變量location
和函數buildUrl
,函數執行環境中定義了變量qs
和url
。with
語句延長了函數執行環境的作用域鏈,解釋器解析標識符href
會首先在變量對象location
搜所,如果沒有延長作用域機制,我們無法解析href
;此外,with
語句不會創建執行環境,如果創建執行環境,當with
語句結束,變量url
將被銷毀,我們無法在函數執行環境中訪問,代碼運行結果顯然情況不是這樣。
沒有塊級作用域
JavaScript沒有塊級作用域,變量的聲明周期和執行環境有關。
var
操作符聲明的變量,將會添加到最近的執行環境的變量對象中。
JavaScript常用的垃圾收集方式是:
- 標記清除
- 引用計數
目前,眾瀏覽器廠商推行J的avaScript的垃圾收集方式是標記清除(舊版本IE除外)。