JavaScriptをやっていると「即時関数(IIFE)」という言葉に出会うことがあります。
ここでは、即時関数(IIFE)とは何か?や使い方、どんな時に使うかを解説しています。
即時関数(IIFE)とは何か?
即時実行関数とは、その場で定義され、すぐに実行される関数のことです。
関数を定義すると同時にその関数を実行するときに使います。
英語で「Immediately Invoked Function Expression」とうため、IIFEと呼ばれることもあります。「Invoked(インボークド)」は発動するという意味です。
即時関数の基本構文
即時関数は以下のように書きます。
(function() {
// 処理
})();
通常の関数との大きな書き方の違いは次の2つです。
なお、末尾の()が即時関数に渡す引数の値を入れる部分になります。
アロー関数で記述する場合
アロー関数で記述すると以下のようになります。
( () => {
// 処理
})();
即時関数に引数を渡す
即時関数に引数を渡す処理は以下のようになります。
(function(name) {
const message = `こんにちは!${name}様`;
console.log(message);
})('田中金之助');
- 出力: こんにちは!田中金之助様
即時関数で戻り値を返す
即時関数で戻り値を返すこともできます。
const res = (function(a, b) {
return a + b;
})(5, 10);
console.log(res);
即時関数の使い方
即時関数自体は「ページロードと同時に処理を実行したい」場合に使用します。
その際、2次的な目的として次のような意図があります。
グローバルスコープの変数の再定義や再代入を避ける
ロードと同時に実行するだけの処理を記述したいとき、グローバルスコープに色々と記述すると、他の関数の中で予期せぬ再定義や再代入が発生して、エラーが表示される可能性があります。
これを防ぐために、即時関数の中でconstやletを使って変数を定義しておけば、グローバルスコープが汚染されることを防ぐことができます。
(function() {
const localVar = 'ローカル変数';
console.log(localVar); //Good!「ローカル変数」を出力
})();
console.log(localVar); //Error! localVar is not defined
初期化コードの実行
ページがロードされたときに実行する初期化用のコードを即時関数に閉じ込めることで、他のコードと干渉しないようにすることができます。
(function() {
// 初期化コード
const initMsg = '初期化完了';
console.log(initMsg);
})();
プライベート変数と関数の定義(カプセル化)
即時関数を使うとプライベート変数や関数を作成することができます。
これにより、データを隠蔽し、外部からアクセスできない変数や関数を定義することができます。
const counter = (function() {
let count = 0; // プライベート変数
return {
increment: function() {
count++;
return count;
},
decrement: function() {
count--;
return count;
}
};
})();
console.log(counter.increment()); // 出力: 1
console.log(counter.decrement()); // 出力: 0
console.log(counter.count); // undefined
ライブラリやモジュールの定義
即時関数を使うことで、ライブラリ内のすべての変数や関数をそのライブラリのスコープ内に閉じ込め、グローバルスコープと干渉しないようにすることができます。
const myLibrary = (function() {
const privateVar = 'プライベート変数';
return {
publicMethod: () => {
console.log(privateVar);
}
};
})();
myLibrary.publicMethod(); // 出力: プライベート変数
console.log(myLibrary.privateVar); // undefined
変数「pribateVar」はプロパティとして呼び出すことはできず、戻り値の中に記述されたpublicMethodといプロパティの実行結果でのみ取得することができます。
クロージャーを使ったデータの永続化
即時関数はクロージャーを使ってデータを永続化する場合にも便利です。
クロージャーを使うことで、関数内のデータを関数外部からアクセス可能にする一方で、直接の変更を防ぐことができます。
const getCounter = (function() {
let count = 0;
return function() {
return ++count;
};
})();
console.log(getCounter()); // 出力: 1
console.log(getCounter()); // 出力: 2
console.log(getCounter()); // 出力: 3
getCounterを呼び出す度に、中の関数が実行されます。