IIFEのようなデザインパターンを理解するための鍵は、ES6の前では、JavaScriptは関数スコープのみを特徴としていたため、ブロ JAVASCRIPTのES6バージョンは、新しいlet
const
キーワードを使用してブロックスコープを実装しているため、これは
Evaluation contextEdit
ブロックスコープの欠如は、forループ内で定義された変数が、その定義を囲む関数の先頭に”掲揚”することを意味します。 外部関数(反復を含む)によって変更された変数に依存する関数を評価することは困難な場合があります。 関数の定義と呼び出しの間に値を更新すると、ループなしでこれを見ることができます。
var v, getValue;v = 1;getValue = function () { return v; };v = 2;getValue(); // 2
v
getValue()
がループ内で定義されている場合、意図しない結果
以降、関数はv
を引数として渡し、内部関数の実行コンテキストを保持してすぐに呼び出されます。p>
var v, getValue;v = 1;getValue = (function (x) { return function () { return x; };})(v);v = 2;getValue(); // 1
これは次のコードと同等です:
var v, getValue;v = 1;function f(x) { return function () { return x; };};getValue = f(v);v = 2;getValue(); // 1
David Hermanの効果的なJavaScriptには、ループ内の評価コンテキストの問題を示す例が含まれています。 Hermanの例は意図的に複雑ですが、ブロックスコープの同じ欠如から直接発生します。
プライベート変数とアクセサーの確立edit
IIFEsは、後で使用するためにいくつかのプロパティを公開しながら、アクセス可能な関数のプライベートメソ 次の例は、IIFEsのAlmanの投稿から来ています。
// "counter" is a function that returns an object with properties, which in this case are functions.var counter = (function () { var i = 0; return { get: function () { return i; }, set: function (val) { i = val; }, increment: function () { return ++i; } };})();// These calls access the function properties returned by "counter".counter.get(); // 0counter.set(3);counter.increment(); // 4counter.increment(); // 5
グローバル環境からcounter.i
counter
i
i
を宣言していないため、エラーが発生します。