このことを考慮:
(function(){
var sobriety = [];
window.inception = function() {
var i = 0,
j = 0,
inner_level = { i: i },
level = { level: inner_level },
food = {};
return function() {
var new_level = {
level: level.level
};
new_level[i] = 'step ' + i;
new_level.level.i = i;
sobriety[i++] = new_level;
};
};
window.show_my_sobriety = function() { console.log(sobriety); };
})();
var agent = inception();
agent(); agent(); agent();
show_my_sobriety();
JSフィドル。
i
この例はやや洗練されていることは認めますが、(プリミティブ)とinner_level
(参照型)の違いを示すために作成する必要がありました。
ここに、ローカルに1つの変数があり、(オブジェクトsobriety
のプロパティに割り当てることによって)2つの関数がグローバルになっているモジュールがあります。window
これらのグローバル関数はsobriety
、それを定義したモジュールが終了した後でも変数にアクセスできることに注意してください(in-context
)。
inception
関数は、呼び出されると、5つの変数を定義します。2つのスカラー(i
とj
)と3つの参照(inner_level
、level
とfood
)です。次に、関数を定義してそれを返します。
この関数は明らかにi
and level
(同じコンテキスト)とsobriety
(外部レベルのコンテキスト)にアクセスしますが、 j
andにはアクセスしませんfood
。window.inception
したがって、後者は完了直後にGCによって収集されます。ただし、前者は収集されないままです。内部関数によって参照されるためです。
今トリッキーな部分。inner_level
この関数にはアクセスは表示されませんlevel
が、同じ名前のオブジェクトのプロパティの値であるため、引き続きアクセスされます。そして、結果を確認すると、3つの要素すべてが同じlevel.i
値(2に等しい)を持っていることがわかります。これは、「コンテキスト内の変数によって参照される変数」によって理解されるものです。