このクロージャの動作によって混乱します。私は閉鎖に関するいくつかのSOの記事(this oneを含む)とMDNの文書を読んだが、この動作の説明は見ていない。クロージャの変数を返すと参照の代わりにコピーが作成されています
下のコードサンプルでは、変数cache
と、それを変更する関数preload
と、その値を記録する関数report
を含むクロージャを作成しています。また、渡されたオブジェクトにそれらへの参照を添付する。
'use strict';
var o = {};
(function(obj) {
var cache = {'initialized': false};
function preload(assets, done) {
console.log('Preloading. Value of cache is', cache);
cache = {};
for (var i = 0; i < assets.length; i++) {
cache[assets[i]] = assets[i];
}
}
function report() {
console.log('Cache from inside is ', cache);
}
function get_cache() {
return cache;
}
obj.cache = cache;
obj.preload = preload;
obj.report = report;
})(o);
// {initialized: false}, as expected
o.report();
// {initialized: false}, as expected
console.log('Cache from outside is ', o.cache);
// I expect this to change cache to {1:1, 2:2, 3:3}
o.preload([1, 2, 3]);
// {1:1, 2:2, 3:3}, as expected
o.report();
// {initialized: false}, NOT as expected. Why?
console.log('Cache from outside is ', o.cache);
私の期待を閉鎖が提供obj
からcache
を添付するとき、それはクロージャ内の変数への参照を代入していることを私の理解に基づいています。しかし、私が見ているふるまいは、obj.cache
が閉鎖のcache
のコピーを得ていることを示唆しています。
cache
のコピーはいつ作成されますか?その理由は何ですか?あなたが最初にobj.cache = cache;
を呼び出すと
なぜ 'get_cache'ではなく、' cache'変数の初期値を公開していますか? – Bergi
あなたはコピーを作成しているので、 'cache = {}'。クロージャーだけが変数 'cache'そのものであることに注意してください。変数 'obj.cache'はクロージャではなく、CやJavaや他の言語のような通常の参照/ポインタ代入です。そのため、 'obj.cache'は' cache'によって指されるのと同じオブジェクトを指すが、変数 'cache'は指さない。つまり、 'obj.cache = cache'はキャッシュへのポインタを値で割り当てます(ほとんどのプログラミング言語のようにポインタのコピーを作成します) – slebetman