LoginSignup
11

More than 5 years have passed since last update.

for文内での関数定義

Last updated at Posted at 2017-09-23

for文内で関数定義し、定義した関数を実行した時の挙動で困ったのでメモ

for文内で関数定義

for文内で関数を定義して、それをfor文の外で呼び出して実行しようとしました。

sample1.js
var functions = []
for (var i = 0; i < 3; i++) {
    functions.push(function(){
        console.log(i);
    });
}
functions[0]();
functions[1]();
functions[2]();

0,1,2と表示されることを期待していましたが結果は以下のように。

3
3
3

あれ?と思ったのですが、少し考えるとループを回している変数iは定義したfunctionの外のスコープにあることに気がつきました。

即時関数でスコープを作る

0,1,2と表示させるために、定義したfunctionでスコープを作りスコープ内で定義した変数を参照させるようにします。そこで即時関数を用います。即時関数は今あるスコープとは別に新たなスコープを作成するので、即時関数を使用して以下のように書き換えました。

sample2.js
var functions = [];
for (var i = 0; i < 3; i++) {
    //即時関数
    (function () {
        var x = i;
        functions.push(function () {
            console.log(x);
        });
    })();
}
functions[0]();
functions[1]();
functions[2]();

すると期待通りの結果に。

0
1
2

即時関数は、定義+実行の目的以外に、今回の場合やスコープ汚染を防ぐために利用するそうです。

letを使う

ES6で追加された宣言letを使ってfor文を回します。letによってfor文のブロックでスコープを構築します。

sample3.js
var functions = [];
for (let i = 0; i < 3; i++) {
    functions.push(function(){
        console.log(i);
    });
}
functions[0]();
functions[1]();
functions[2]();

すると期待通りに。

0
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11