JavaScript Closure VS. Local
-
21-12-2019 - |
質問
私は、直ちに呼ばれた閉鎖によって囲まれたJavaScriptメインファイルを持っています(汚染されないように 'global':
(function () {
"use strict";
var closureVariable = [];
...
}());
.
私のコードがセミコロンの代わりにコンマを持っていたように、関数ヘッダーから変数を削除するときに単純で骨の符号化エラーを作成しました。
function fred () {
var i,
closureVariable = [1,2,3,4];
confused();
}
function confused () {
console.log(closureVariable); // Prints '[]'
}
.
確かに 'var i'行の欠落セミコロンが問題でした。しかし、私が起こるべき行動は、私の現在のローカル定義変数「closurevariable」が上位スコープ定義をシャドウしたはずであり、そして私のローカル定義変数の値はスコープチェーンで遅くなっているべきであるべきです(つまり、関数 '混乱している' [1,2,3,4] ';
ここでJavaScriptスコープチェーンについて理解していないの?
解決
あなたが期待しているのは、動的スコープとして知られています。これは有効な言語設計の選択ですが、今日は劣っていましたが、広く考慮されています。JavaScriptが何であるかだけではありません。多くの人気のある言語のように、JavaScriptは字句スコープを使用しています。つまり、confused
のスコープはfred
の子範囲とは見なされません。fred
がfred
を呼び出すという事実は効果がありません。
他のヒント
var i,
closureVariable = [1,2,3,4];
.
は、fred
関数およびこのスコープで定義されている関数で2つの新しい変数を作ります。
これらの変数は、たとえそれらが同じ名前を持つ場合でも、fred
スコープの外部で定義されている変数とは完全に異なります。
シャドウイングは、"closureVariable"
という名前の変数が外部スコープに同じ名前を持つ変数への直接アクセスを防ぐことを意味します。
セミコロンを省略してclosurevariableを再定義した場合、Fred関数のコンテキストでのみ再定義されました。混乱した関数はあなたの閉鎖の文脈に存在するので、それはまだ元のclosurevariableを見ています。あなたがFred関数の内側にあなたの混乱した関数を定義したなら、それは新しいclosurevariableを見るでしょう[1,2,3,4]
(function () {
"use strict";
var closureVariable = [];
function fred () {
var i,
closureVariable = [1,2,3,4];
function confused () {
console.log(closureVariable);
}
confused(); // print [1,2,3,4]
}
})();
.
またはFred()
の外部から混同したい場合(function () {
"use strict";
var closureVariable = [];
var confused;
function fred () {
var i,
closureVariable = [1,2,3,4];
confused = function () {
console.log(closureVariable);
}
}
confused(); // print [1,2,3,4]
})();
.