JavaScript 的可執行代碼,具備執行上下文,而每一個上下文包括如下 3 個屬性:javascript
變量對象提供了當前環境所需的變量和函數
做用域鏈用於保證 JS 中變量和函數有序地訪問
this 爲函數提供了執行者對象java
一個上下文的執行週期能夠用下圖示意:
express
本文就來介紹執行上下文中的變量對象
。數組
那什麼是變量對象呢?先看定義:瀏覽器
變量對象是與執行上下文相關的數據做用域,用於存儲執行上下文中的變量和函數聲明。bash
不一樣的執行上下文,變量對象會有一些差異。接下來就分別針對不一樣的上下文討論其區別。閉包
全局對象(Global object) 是在進入任何執行上下文以前就已經建立了的對象; 這個對象只存在一份,它的屬性在程序中任何地方均可以訪問,全局對象的生命週期終止於程序退出那一刻。app
在全局代碼的上下文執行環境中,變量對象就是全局對象,在瀏覽器中,就是 window 對象。函數
此時,咱們能夠用 this 和 self 來訪問到全局對象,也就是它自己post
console.log(this) // window
console.log(self) // window
複製代碼
其次,全局對象初始建立階段將 Math、String、Date、parseInt 等函數做爲自身方法,還會把全局變量做爲本身的屬性。
用僞代碼表示就是:
global = {
Math: <...> Date: <...> window: global // 引用自身 } 複製代碼
咱們已經知道,變量對象存儲量執行上下文中的函數聲明和變量,在函數上下文中,多了arguments(函數參數列表)
, 一個類數組對象。
用僞代碼來表示:
VO = {
arguments: Arguments,
variables: undefine,
functionName: <Function reference>
}
複製代碼
函數未進入執行階段以前,變量對象中的屬性都不能訪問!可是進入執行階段以後,變量對象轉變爲了活動對象(activation object)。
因此,在函數上下文中,咱們將活動對象(activation object)做爲變量對象,活動對象最開始只包含一個變量就是 arguments 對象(這個對象是全局環境中沒有的)。
arguments 的屬性值 Arguments 它包括以下屬性:
咱們再一次來看這個過程圖:
建立階段
全局對象初始化的時候,就將變量對象引用了自身。 而函數的建立卻有須要注意的地方。
函數在建立階段就建立了變量對象
其中,變量對象包括:
進入執行上下文時,函數聲明和變量聲明都會提早,這就是聲明提高,可是變量聲明的值都是undefined,而函數聲明的變量已經能夠指向函數。變量聲明的優先級最低。
看下面這段代碼:
function foo(a, b) {
var c = 10;
function d() {}
var e = function _e() {};
(function x() {});
}
foo(10);
複製代碼
當進入函數 foo 時,其變量對象的表現形式爲:
VO = {
arguments: {
0: 10,
1: undefined,
length: 1
}
c: undefined,
d: <function reference to d>, e: undefined, } 複製代碼
x 是函數表達式,因此不在變量對象當中,e 變量引用的值也是函數表達式,因此變量 e 自己是聲明,因此在變量對象當中。
執行階段
當前進入執行階段,變量對象激活成活動對象,函數會順序執行代碼,改變變量對象的值:
以上代碼就變成:
AO = {
arguments: {
0: 10,
1: undefined,
length: 1
}
c: 10,
d: <reference to function declaration d>,
e: <reference to Function expression to _e>,
}
複製代碼
接下來看一段代碼:
console.log(foo);
function foo() {
console.log("123")
}
var foo = "456";
複製代碼
以上會打印函數,是由於:
變量優先處理函數聲明,再是變量聲明。
再看一段代碼:
if (true) {
var a = 1;
} else {
var b = 2;
}
console.log(a); // 1
console.log(b); // undefined
複製代碼
雖然 else 中的代碼永遠不會被執行,可是 b 的變量聲明在執行以前就默認被設置成 undefined了。
執行上下文包括三個屬性,變量對象,做用域鏈,this, 不一樣的執行上下文,變量對象是有區別的。
全局上下文中,變量對象就是自己。
函數上下文中,變量對象包括:arguments, 函數聲明,變量聲明。在函數建立階段,變量對象有默認值,進入執行階段後,變量對象會被激活成活動對象,而後變量對象的值被順序改變。
歡迎關注個人我的公衆號「謝南波」,專一分享原創文章。