在學會了變數範圍和 lexical environment 後,我們就可以用它來檢驗一下閉包發生的原因,畢竟閉包是 JavaScript 作用範圍規則運作時的一個副作用。
function Foo() {
var parm = 0;
this.getParm = function() {
return parm;
};
this.increase = function() {
parm++;
}
}
var foo1 = new Foo();
console.log(foo1.parm === undefined);
foo1.increase();
console.log(foo1.getParm() === 1);
var foo2 = new Foo();
console.log(foo2.getParm() === 0);
每次當我們使用關鍵字 new
呼叫一個 constructor function 時,就建立了一個新的 lexical environment,它負責追踪 constructor function 的區域變數。在例子裡,新的 Foo
環境用來追踪 parm
變數。
函式在建立時,同時會在內部屬性[[Environment]]
建立起對自己所屬 lexical environment 的參照。在 constructor function 裡的二個函式 getParm
和increase
原本就參照 constructor function 環境,在成為新物件的方法後,也可以在物件外部被呼叫,這也表示我們已經建立了一個包含parm
變數的閉包。