Edited at

JavaScriptの即時関数にハマった話


概要


  • ハマって思い出したシリーズ。より正確には、完全に忘れてて時すでにお寿司シリーズ。

  • 以下備忘録。


前提


  • 以下のようなコードがある

const hoge = function() {

console.log("call hoge function");
}

(function() {
console.log("call anonymous function");
})();


現象


  • 最初のコードは無名関数が hoge に代入にされているだけにみえる。

  • だけど実際には hoge は実行されてしまう。

  • ブラウザ上で実行すると下記のようになる。

DevTools_-_qiita_com_igayamaguchi_items_ac48b7e12890351ee55a.png



  • call hoge function が表示されてるので hoge が実行されているのがわかる


原因

Q. なぜ hoge が実行されてしまうのか? -> A. セミコロンが省略されてるから

const hoge = function() {

console.log("call hoge function");
} // <- ここにセミコロンがないのが原因

(function() {
console.log("call anonymous function");
})();

セミコロンが無いので文がまだ続いてると解釈され以下のようなコードを書いてるのと等価になる。

const hoge = function() {

console.log("call hoge function");
}(function() {
console.log("call anonymous function");
})();

つまり代入する前に function() を定義したそばから function()() として実行されてしまう。


対処


  • 代入文の最後にセミコロンを書く

const hoge = function() {

console.log("call hoge function");
}; // <- セミコロンかく

(function() {
console.log("call anonymous function");
})();


  • 即時関数の前に セミコロンを書く

const hoge = function() {

console.log("call hoge function");
}

;(function() { // <- "(" の前に";" を書く
console.log("call anonymous function");
})();


  • この問題は 即時関数セミコロンの自動挿入 など話題と絡めてよく知られている。

  • 最近はセミコロンを書かないスタイルを採用するケースは増えているので、即時関数を書く必要がある時は ; を先頭につけておいた方が親切。

  • 古のjQuery の プラギンはそうやってた。


即時関数 is 何?


その他参考