【JavaScript】forループ内でクロージャを生成する

Javascriptにおけるforループのクロージャって意識したことあるだろうか。

例えばよく出くわすこんなコード。実はこれには問題がある。

for (var i = 0, l = elm.length; i < l; i++;) {
    elm[i].addEventListener('click', function() {
        console.log(i);
    }, false);
}

問題

取得した要素をforループで回してクリックイベントを設定してクリックした時にループのカウントを参照する。

しかしこれだとクロージャが生成されず、カウンタ変数が保持されない為どの要素から参照しても該当するカウントはlength値の値になる。

See the Pen GJwwLM by Youhei Isokawa (@yuhiisk) on CodePen.

※コンソールで確認可能

解決策

ループブロックの中で即時関数を使うとクロージャを生成出来る。
即時関数の引数にカウンタ変数を渡すところがポイントだ。

for (var i = 0; i < length; i++;) {
    (function(n) {
        elm[n].addEventListener('click', function() {
            console.log(n);
        }, false);
    })(i);
}

See the Pen MwzzMd by Youhei Isokawa (@yuhiisk) on CodePen.

もしあなたがもっとJavaScript Ninjaになりたいなら

同じ問題の解決策がJavascript Ninjaで紹介されていて、なるほどと思った。

この書き方はなかなか思いつかない。forループのブロックに即時関数を指定する。
この方がスッキリ書けるのでオススメだ。

for (var i = 0; i < length; i++;) (function(n) {
    elm[n].addEventListener('click', function() {
          console.log(n);
    }, false);
})(i);

See the Pen OVarLZ by Youhei Isokawa (@yuhiisk) on CodePen.

五十川 洋平(Yohei Isokawa)

五十川 洋平(Yohei Isokawa)

フロントエンドエンジニア/面白法人カヤックなどのWeb制作会社に勤務したのち、故郷の新潟に戻り独立。JSフレームワークAngularやFirebase、Google Cloud Platformを使ったWebアプリ開発が得意。 また、Udemyのプログラミング解説の講師、writer.appの自主開発や上越TechMeetupの主催などを行っています。

プロフィール

©Copyright 2022 Yohei Isokawa All Rights Reserved.