即時呼び出し関数式(IIFE 、発音は「iffy」、IPA /ˈɪf.i/)は、関数スコープを使用してレキシカルスコープを生成するプログラミング言語の慣用句です。これは、 CommonJSやESモジュールなどのより標準化されたソリューションが導入される前は、モジュールプログラミングをサポートする方法としてJavaScript [1]で人気がありました。[2]
即時に呼び出される関数式を使用すると、ブロック内からの変数の巻き上げを回避し、グローバル環境の汚染を防ぎ、同時に関数内で定義された変数のプライバシーを維持しながらメソッドへのパブリック アクセスを許可できます。つまり、関数と変数をラップして、グローバル スコープから除外し、ローカル スコープを与えます。
使用法
即時呼び出し関数式は、さまざまな方法で記述できます。[3]一般的な慣習は、関数式(およびオプションでその呼び出し演算子)をグループ化演算子[4]で括り、パーサーに式を期待することを明示的に伝えることです。それ以外の場合、ほとんどの場合、パーサーはfunctionキーワードに遭遇すると、それを関数式ではなく関数宣言(ステートメント)として扱います。[5] [6]
( function () { /* ... */ })(); ( function () { /* ... */ }()); (() => { /* ... */ })(); // ES6 矢印関数を使用(ただし括弧は外側のみで使用可能)
式が期待されるコンテキストでは、括弧で囲む必要はありません。
f = function () { /* ... */ } ( ); true && function () { /* ... */ }(); 0 , function () { /* ... */ }();
変数をスコープに渡すには、次のようにします。
(関数( a 、b ) { /* ... */ })( "hello" 、"world" );
先頭の括弧は、JavaScript の自動セミコロン挿入(ASI) が問題を引き起こす可能性がある 1 つのケースです。式は、前の行の最後の項への呼び出しとして解釈されます。オプションのセミコロンを省略するスタイルでは、セミコロンは括弧の前に置かれ、防御セミコロンと呼ばれます。[7] [8]たとえば、次のようになります。
a = b + c ;(関数() { // コード})();
... として解析されるのを避けるためですc()。
例
IIFEのようなデザインパターンを理解する鍵は、ES6より前のJavaScriptでは関数スコープのみ(ブロックスコープがない)であり、クロージャ内で参照によって値を渡していたことを認識することです。[9]しかし、ES6バージョンのJavaScriptではnewキーワードとキーワードを使用してブロックスコープが実装されているため、これは当てはまりません。[10]letconst
// ES6 以前: IIFE を使用してスコープを作成する
var foo = 1 ; var bar = 2 ; ( function (){ var foo = 3 ; // 外側の `foo` をシャドウしますbar = 4 ; // 外側の `bar` を上書きします})(); console . log ( foo , bar ); // 1 4
// ES6 以降: 中括弧を let と const と組み合わせて使用してスコープを作成する
const foo = 1 ; let bar = 2 ; { const foo = 3 ; // 外側の `foo` をシャドウするbar = 4 ; // 外側の `bar` を上書きする} console . log ( foo , bar ); // 1 4
評価コンテキスト
ブロックスコープがないということは、たとえばfor ループ内で定義された変数の定義が、その関数の先頭に「持ち上げられる」ことを意味します。外側の関数によって変更された変数 (反復処理を含む) に依存する関数を評価することは困難です。関数の定義と呼び出しの間に値を更新すると、ループなしでこのことがわかります。[11]
let v , getValue ; v = 1 ; getValue = function () { return v ; }; v = 2 ;
getValue (); // 2
手動で更新すると結果は明白に思えるかもしれませんが、ループ内で定義されている
v場合は意図しない結果が生じる可能性があります。getValue()
以降、関数はv引数として渡され、内部関数の実行コンテキストを保持したまま直ちに呼び出されます。[12]
v 、getValueとします。v = 1 ; getValue = ( function ( x ) { return function () { return x ; }; })( v ) ; v = 2 ;
getValue (); // 1
これは次のコードと同等です。
let v , getValue ; v = 1 ; function f ( x ) { return function () { return x ; }; }; getValue = f ( v ); v = 2 ;
getValue (); // 1
プライベート変数とアクセサの確立
IIFEは、アクセス可能な関数のプライベートメソッドを確立しながら、後で使用するためにいくつかのプロパティを公開するのにも役立ちます。[13]次の例は、AlmanのIIFEに関する投稿からの抜粋です。[1]
// "counter" は、プロパティ (この場合は関数) を持つオブジェクトを返す関数です。let counter = ( function () { let i = 0 ;
戻り値: get : function () { return i ; }, set : function ( val ) { i = val ; }, increment : function () { return ++ i ; } }; })();
// これらの呼び出しは、「counter」によって返される関数プロパティにアクセスします。
counter . get (); // 0 counter . set ( 3 ); counter . increment (); // 4 counter . increment (); // 5
グローバル環境から にアクセスしようとするとcounter.i、 は呼び出された関数内に囲まれており、 のプロパティではないため、未定義になりますcounter。同様に、 にアクセスしようとするとi、グローバル環境で宣言されていないため、エラーが発生しますi。
用語
もともと「自己実行型匿名関数」として知られていましたが、[14] Ben Alman は、comp.lang.javascript で議論が起こった直後に、この慣用句のより意味的に正確な名前として現在の用語 IIFE を導入しました。[1] [15] [16]
特に、即時に呼び出される関数は本質的に匿名である必要はなく、ECMAScript 5の厳密モードではが禁止されているためarguments.callee、[17]元の用語は誤った名称になっています。
参照
参考文献
- ^ abc Alman, Ben (2010年11月15日). 「Immediately Invoked Function Expressions」. 2017年12月1日時点のオリジナルよりアーカイブ。2019年1月18日閲覧。
- ^ McGinnis, Tyler (2019年1月15日). 「JavaScript モジュール: IIFE から CommonJS、ES6 モジュールまで」. ui.dev . 2021年8月18日閲覧。
- ^ Lindley, Cody (2013). JavaScript Enlightenment . O'Reilly. p. 61. ISBN 978-1-4493-4288-3。
- ^ 「グループ化演算子」。Mozilla Developer Network。2023年10月2日。
- ^ ザカス、ニコラス (2012)。Maintainable JavaScript。O'Reilly。p . 44。ISBN 978-1-4493-2768-2。
- ^ Axel Rauschmayer. 「ExploringJS」.
- ^ 「JavaScript セミコロン挿入: 知っておくべきことすべて」 2010 年 5 月 28 日。2017 年 10 月 2 日時点のオリジナルよりアーカイブ。
- ^ Marohnić, Mislav (2010年5月7日). 「JavaScript のセミコロンはオプションです」。2017年8月8日時点のオリジナルよりアーカイブ。
- ^ ハフェルベケ、マリジン (2011).雄弁な JavaScript。スターチプレスは不要です。 29-30ページ。ISBN 978-1-59327-282-1。
- ^ Orendorff, Jason (2015 年 7 月 31 日). 「ES6 の詳細: let と const」. Mozilla Hacks – Web 開発者ブログ. Mozilla . 2024 年10 月 16 日閲覧。
- ^ Alman, Ben. 「simple-iife-example.js」。Github 。 2013年2月5日閲覧。
- ^ Otero, Cesar; Larsen, Rob (2012). Professional jQuery . John Wiley & Sons. p. 31. ISBN 978-1-118-22211-9。
- ^ Rettig, Pascal (2012).プロフェッショナル HTML5 モバイルゲーム開発. John Wiley & Sons. p. 145. ISBN 978-1-118-30133-3。
- ^ ジョン・レジグ (2006).プロの JavaScript テクニック。アプレス。 p. 29.ISBN 978-1-4302-0283-7。
- ^ Osmani, Addy (2012). JavaScript デザインパターンの学習. O'Reilly. p. 206. ISBN 978-1-4493-3487-1。
- ^ Baagoe, Johannes. 「関数の定義内の括弧を閉じ、その後にその呼び出しを行う」 。2010年4 月 19 日閲覧。
- ^ 「Strict モード」。Mozilla JavaScript リファレンス。Mozilla Developer Network。2013年2 月 4 日閲覧。
外部リンク
- 「関数と関数のスコープ」。Mozilla JavaScript リファレンス。Mozilla Developer Network。2013年2 月 4 日閲覧。
