こんにちは!Reiです(˵ •̀ ᴗ – ˵) ✧
関数って、普通は定義してからあとで呼び出しますよね。
でもJavaScriptには、作った瞬間にその場で実行される関数 もあるんです!
それが IIFE(イフィー) 。「即時実行関数」とも呼ばれていたりします 👀
見た目がちょっと独特なので、慣れないと「なんでわざわざこんな書き方するの?」となりがちな箇所でもあります。
今回は、IIFE の仕組みと使いどころについてクイズ形式で整理していきます!
どこで使うものなのか、ぜひ考えながら見てみてください ᥫᩣ ̖́-
第1問 IIFE を実行すると?
まずはここから!
(function() {
const secret = "秘密のメッセージ";
console.log("実行中!");
})();
console.log(secret);
このコードを実行するとどうなるでしょうか?
- “実行中!” のあとに “undefined” が表示される
- “実行中!” のあとに “秘密のメッセージ” が表示される
- “実行中!” のあとにエラーが発生する
- 最初の関数が実行されない
正解は… (ここをクリック!)
3の “実行中!” のあとにエラーが発生する でした!
(難しかったかな?)
解説 !!
IIFE は、その場で関数を定義してそのまますぐに関数を実行します。
なので、
(function() {
const secret = "秘密のメッセージ";
console.log("実行中!");
})();
この部分はすぐに実行されて、 "実行中!" が表示されます。
ただし、secret は関数の中で const 宣言されている変数のため、関数の外側からはアクセスすることができません 💦
そのため、
console.log(typeof secret);
は ReferenceError: secret is not defined というエラーが出力されるのです。
ここで大事なポイントが、IIFE の中で定義した変数は外に漏れない というところ!
「その場だけで使う変数」を安全に閉じ込められるのが IIFE の特徴です!
第2問 なんで () で囲むの?
次はこちら!
function() {
console.log("ok");
}();
これはエラーになりますが、
(function() {
console.log("ok");
})();
これは動きます。
さて、なぜ () で囲むと動くのでしょうか?
- 関数が速くなるから
- JavaScript に「これは式だよ」と伝えるため
console.logが特別扱いされるから
正解は… (ここをクリック!)
2の「JavaScript に「これは式だよ」と伝えるため」でした!
解説 !!
ここは IIFE でかなり大事なポイント 💡
IIFEは、関数を「値」として扱ってから実行する書き方です。
JavaScript は、文の先頭にある function を見ると、
「これは関数宣言かな?」と判断します。
でも関数宣言には名前が必要なので、
function() {}
のように名前がないとエラーになります。
でも、
(function() {})
のように、関数全体を ( ) で囲むことで、「これは宣言じゃなくて、値として扱うよ(=関数そのもの)」と JavaScript に伝えることができます。
そして式として認識されれば、その直後に ( ) を付けることでそのまま実行できるようになります。
つまり IIFE は、
(関数式)();
という形で、関数を定義すると同時にその場で実行することで成り立っているのです。
少し独特に見えますが、「宣言ではなく値として扱わせるための書き方」と覚えておくと理解しやすいかなと思います!
第3問 IIFE は何のために使う?
次のうち、IIFE の主な目的として一番近いのはどれでしょうか?
- ループを速くするため
- 配列を自動でコピーするため
- 変数を閉じ込めて、外に漏らさないため
正解は… (ここをクリック!)
3の「変数を閉じ込めて、外に漏らさないため」です!
解説 !!
IIFE の最大の目的は、スコープを分けて、変数をカプセル化すること。
カプセル化とは、必要な値や処理をひとまとまりにして、外側から触れられないようにすることです。JavaScript では、変数を関数の中に閉じ込めることで、外から直接参照されない状態を作ります。
昔のJavaScriptでは、変数が意図せず外から見えてしまったり、他のコードと名前がぶつかったりしやすい時代がありました。
そんなときに IIFE で囲むと、
(function() {
const config = "setting";
// この中だけで使う
})();
のように、変数をその関数の中だけに閉じ込められます。
なので IIFE は、
・グローバル汚染を防ぐ
・一度だけ実行する初期化処理を書く
・外に見せたくない値を隠す
といった目的で使われてきました。
第4問 今でも IIFE は使うの?
以前はかなりよく使われていた IIFE ですが、最近は前ほど見かけなくなりました。その理由として大きいのはどれでしょうか?
let/constや ES Modules があるから- JavaScript で関数が使えなくなったから
thisが消えたから
正解は… (ここをクリック!)
1の「let / const や ES Modules があるから」です!
解説 !!
昔は var が中心だったので、スコープを分けたいなら関数で囲むのがかなり重要でした 💡
そのため、古いライブラリや古めのコードではファイル全体が IIFE で包まれていることもよくあります。
でも今のコードは、{ } を使用することでブロックスコープが使えますし、import / export を使うモジュールでもファイル単位でスコープを分けられます。
なので、昔ほど「とりあえず IIFE で囲む」は必要なくなりました。
ただし、今でも使われる場面もあるんです 👀
たとえば、非同期処理をその場で実行したいとき。
(async () => {
const data = await fetch("/api/data");
console.log(data);
})();
このように、async 関数をその場で実行したいときに IIFE が使われます。
「この処理だけ今すぐ実行したい」というケースでは、今でも便利な書き方なのです!
ここまでのポイントおさらい !!
今回の内容をまとめると、次のとおり↓
IIFE
・定義したその場で実行される関数
・(function() {})() の形で書く
・変数を外に漏らさないためによく使われる
丸括弧の意味
・関数を宣言ではなく式として扱わせるため
・式にすることで、直後に () を付けて実行できる
今のJavaScriptとの関係
・昔はスコープ分離のためによく使われていた
・今は let / const や ES Modules があるので出番は減った
IIFE は、今のJavaScriptではあまり見かけない書き方で、実際に使う機会もかなり少なくなっています。
それでも、「なんでこのコードは丸括弧で囲まれてるんだろう?」が分かるようになると、コードの見え方が少し変わってくるはずです 👀
JSではこんな書き方もできるんだなって知ってもらえるのが理解を深める一歩になるはずです 💡
最後に
普段の開発で IIFE を使うことはあまりないですが、古い記事やライブラリ、昔からあるコードでは登場することがあるかもしれないです。
そんなときに
「この関数、なんで丸括弧で囲まれてるの?」
「なんでその場で実行してるの?」
がわかるだけでも、そのコードが何をしたいのかを追いやすくなるはず!
頭の片隅にちょこんと置いておいてくれると嬉しいです ᥫᩣ ̖́-


コメント