javascriptクロージャーの即時評価[複製]
-
06-07-2019 - |
質問
この質問にはすでに回答があります:
次のJavaScriptコードを検討してください:
var a = [];
var f = function() {
for (var i = 0; i < 3; i++) {
a.push(function(){alert(i)});
}
for (var j = 0; j < 3; j++) {
a[j]();
}
};
アラートは3回すべて「3」を出力します。異なる動作が必要です-ループの各反復で、iの現在の値を出力する関数を生成します。つまり異なるインデックスを出力する3つの関数。
アイデアはありますか
解決
i
をパラメーターとして受け入れ、その特定の関数を返す匿名関数を作成します。
for (var i = 0; i < 3; i++) {
a.push((function(i) {
return function() {
alert(i);
}
})(i));
}
for (var j = 0; j < 3; j++) {
a[j]();
}
または同様の操作を行います。関数を配列に追加するパラメーターとして i
を受け入れる匿名関数を作成します。
for (var i = 0; i < 3; i++) {
(function(i) {
a.push(function() {
alert(i);
});
})(i);
}
for (var j = 0; j < 3; j++) {
a[j]();
}
他のヒント
カリーを使用したもう1つのアプローチ:
var a = [];
var f = function() {
for (var i = 0; i < 3; i++) {
a.push((function(a){alert(a);}).curry(i));
}
for (var j = 0; j < 3; j++) {
a[j]();
}
};
// curry implementation
Function.prototype.curry = function() {
var fn = this, args = Array.prototype.slice.call(arguments);
return function() {
return fn.apply(this, args.concat(
Array.prototype.slice.call(arguments)));
};
};
こちらを実行して、上記のスニペットを確認します。
var iterate = (function () {
var i, j = [];
for (i = 0; i < 3; i += 1) {
j.push(i);
alert(j[j.length - 1]);
}
}());
値を出力するだけのためにクロージャは必要ありません。ただし、コードはオブジェクト指向の包含のための関数に含まれている必要があります。関数を実行するために呼び出す必要はありません。
ループの本体を匿名関数に入れることができます:
var a = [];
for(var i = 0; i < 3; i++) (function(i) {
a.push(function() { alert(i); });
})(i)
for(var j = 0; j < 3; j++) {
a[j]();
}
その関数を作成し、&quot; i&quot;のループの値を渡すことにより、引数として、新しい&quot; i&quot;を作成しています。外側の「i」を本質的に隠すループの本体内の変数。配列にプッシュするクロージャーには、新しい変数が表示されます。この変数の値は、最初のループで外部関数関数が呼び出されたときに設定されます。これは、新しい変数を作成するときに別の名前を使用するとより明確になる可能性があります...これは同じことを行います。
var a = [];
for(var i = 0; i < 3; i++) (function(iNew) {
a.push(function() { alert(iNew); });
})(i)
for(var j = 0; j < 3; j++) {
a[j]();
}
&quot; iNew&quot;の値関数はループによってすぐに呼び出されるため、0、1、2の順に割り当てられます。
function(i){alert(i)
所属していません StackOverflow