やったほうがいい:
var o = {};
for(var i = 0; i < 5; i++) {
(function(i) { // <- self-executing anonymus function with a parameter i
o[i] = function () {
console.log(i); // <- i here will be the argument i,
// not the i from the loop
};
})(i); // <- pass i as an argument
}
o[3]();
何が起こるかというと、 iの状態を維持するためにクロージャーと呼ばれるものを作成します。
クロージャとは、内部関数が外部関数への参照を保持し、その変数とパラメーターへのアクセスを取得することを意味します(外部関数が戻った後でも)。
閉鎖の簡単な例は次のとおりです。
function outer(arg) {
var variable = 5;
arg = 2;
function inner() {
alert(variable); // <- the inner function has access to the variables
alert(arg); // and parameters of the outer function
}
}
自己実行(自己呼び出し、または即時)関数は、宣言された直後に呼び出される関数です。
(function() {
alert("executed immediately");
})();
両方の組み合わせと、関数のみがJavascriptでスコープを持っているという事実は、 iの状態を保持する新しい関数でスコープを作成するための上記の手法につながります。そうでなければ、クロージャーのために内部関数によって変更されます。