Javascript

ループでイベントリスナを登録したい時の落とし穴

配列やオブジェクトから一括してイベントリスナを登録したい時にfor文で回してやろうとして下記の様に書くと、

var arg = ['aa', 'bb', 'cc'];
for (var key in arg) {
	window.addEventListener('scroll', function () {
		console.log(arg[key]);  //cc cc cc
	}, false);
}

イベントリスナに最後のkeyだけ渡されて最後の値の連呼になるので、そんな時は、

var arg = ['aa', 'bb', 'cc'];
for (var key in arg) {
	(function(key_) {
		window.addEventListener('scroll', function () {
			console.log(arg[key_]); //aa bb cc
		}, false);
	}(key));
}

こう。ココをこうこうこう。

setTimeoutなんかの時も同じ

var arg = ['aa', 'bb', 'cc'];
for (var key in arg) {
	(function(key_) {
		setTimeout(function() {
			console.log(arg[key_]);
		}, 50);
	}(key));
}

イベントリスナやsetTimeoutは関数を別のタイミングで実行するので、for文を回している時の変数等を参照しようとしてもダメ。

著者