ここでは第一原理を使用する必要があります。Javascriptは字句スコープを使用します。これは、実行コンテキストのスコープがコードの定義方法(字句)によって決定されることを意味します。
関数の定義は、関数内で「閉じられている」 ため、クロージャが作成されるBar
原因であると言えます。msg
クロージャーの実際の作成は実行時に行われます(これはmsg
、実行されるまでコンピュータープログラムでは何も起こらないため、トートロジーステートメントのようなものです)。実行時の変数の値などをチェーンの上位で確認します。Bar
Bar
Foo
私はあなたの質問に2つの答えを与えます。衒学的な答えは次のとおりです。どちらの機能自体もクロージャーではありません。これは、関数内の変数の定義であり、実行時の関数の実行コンテキストと組み合わされて、クロージャーを定義します。一般的な答えは次のとおりです。変数を閉じる関数はすべてクロージャです(あなたの場合はバー)。
Javascriptを使用するときに誰もが遭遇する問題を考えてみてください。
function A(x) {
var y = x, fs = [];
for (var i = 0; i < 3; i++) {
fs.push(function(){
console.log (i + " " + x);
})
}
fs.forEach(function(g){g()})
}
A('hi')
ほとんどの人は、これにより「hi 1」、「hi 2」、「hi3」の出力が生成されると言うでしょう。ただし、「hi3」を3回生成します。配列に追加される関数の定義だけで、外部関数で定義された変数を使用してクロージャーを作成した場合、これはどのようになりますか?
これは、クロージャを定義するために実行コンテキストが必要なためです。これは、実行時まで発生しません。配列内の関数の実行時にi
、値は。になります3
。ステートメントではforEach
、これが実行コンテキストであるため、出力では常に3が使用されます。