概要
- ハマって思い出したシリーズ。より正確には、完全に忘れてて時すでにお寿司シリーズ。
- 以下備忘録。
前提
- 以下のようなコードがある
const hoge = function() {
console.log("call hoge function");
}
(function() {
console.log("call anonymous function");
})();
現象
- 最初のコードは無名関数が
hoge
に代入にされているだけにみえる。 - だけど実際には
hoge
は実行されてしまう。 - ブラウザ上で実行すると下記のようになる。
-
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 何?
- グローバルスコープを汚染しないように、コード全体を無名関数でくくって、関数スコープでコードを動かすテク
- 参考: https://qiita.com/katsukii/items/cfe9fd968ba0db603b1e