JS 変数の値 (参照ではなく) を関数に渡すにはどうすればよいですか?[重複]
-
24-09-2019 - |
質問
この質問にはすでに答えがあります:
- ループ内の JavaScript クロージャ – 簡単な実践例 44 件の回答
これは私が実行しようとしているものの簡略版です:
for (var i = 0; i < results.length; i++) {
marker = results[i];
google.maps.event.addListener(marker, 'click', function() {
change_selection(i);
});
}
しかし、すべてのリスナーがresults.lengthの値(forループが終了したときの値)を使用していることがわかりました。追加時に i への参照ではなく i の値を使用するようにリスナーを追加するにはどうすればよいですか?
解決
最近のブラウザでは、あなたはブロックスコープ変数を作成するlet
またはconst
キーワードを使用することができます:
for (let i = 0; i < results.length; i++) {
let marker = results[i];
google.maps.event.addListener(marker, 'click', () => change_selection(i));
}
<時間>
古いブラウザでは、関数のパラメータとして渡すことで、現在の状態で変数を保存し、別のスコープを作成する必要があります:
for (var i = 0; i < results.length; i++) {
(function (i) {
marker = results[i];
google.maps.event.addListener(marker, 'click', function() {
change_selection(i);
});
})(i);
}
匿名関数を作成し、最初の引数として変数でそれを呼び出すことによって、あなたが関数に値による受け渡しと閉鎖を作成しています。
他のヒント
と同様に閉鎖、あなたはfunction.bind
を使用することができます
google.maps.event.addListener(marker, 'click', change_selection.bind(null, i));
は呼び出された関数の引数としてi
の値を渡します。 (null
は、あなたがこのような場合には必要ありませんthis
を、結合のためである。)
function.bind
はプロトタイプフレームワークによって導入されたとのECMAScript第5版で標準化されています。すべてのサポートそれをネイティブのブラウザまで、あなたはクロージャを使用して独自のfunction.bind
のサポートを追加することができます:
if (!('bind' in Function.prototype)) {
Function.prototype.bind= function(owner) {
var that= this;
var args= Array.prototype.slice.call(arguments, 1);
return function() {
return that.apply(owner,
args.length===0? arguments : arguments.length===0? args :
args.concat(Array.prototype.slice.call(arguments, 0))
);
};
};
}
クロージャ:
for (var i = 0, l= results.length; i < l; i++) {
marker = results[i];
(function(index){
google.maps.event.addListener(marker, 'click', function() {
change_selection(index);
});
})(i);
}
編集、2013:これらは現在、一般的に「 IIFE
あなたはクロージャで巻き取ります。 <ストライキ> ここで閉鎖とどのように彼らと仕事への記事です。ページ上の実施例5をチェックしてください。それはあなたがしているに対処するシナリオです。ストライキ>
EDIT:四年後に、リンクが死んでいます。上記問題の根本は、(具体的にfor
)marker = results[i]
ループ形の閉鎖ということです。 marker
がaddEventListener
に渡されるとして、あなたはクロージャの副作用を参照してください。それが最終的に最後の反復後に閉鎖を経由して「保存」だ前に、共有「環境」は、ループの各反復で更新されます。 MDNは非常によくこれを説明しています。に
for (var i = 0; i < results.length; i++) {
marker = results[i];
google.maps.event.addListener(marker, 'click', (function(i) {
return function(){
change_selection(i);
}
})(i));
}
私たちは、iの値を格納するために一時変数を定義することができると思います。
for (var i = 0; i < results.length; i++) {
var marker = results[i];
var j = i;
google.maps.event.addListener(marker, 'click', function() {
change_selection(j);
});
}
私はかかわらず、それをテストしていません。