cheia înțelegerii modelelor de proiectare, cum ar fi IIFE, este să realizăm că, înainte de ES6, JavaScript conținea doar domeniul de aplicare al funcției (lipsind astfel domeniul de aplicare al blocului), trecând valori prin referință în interiorul închiderilor. Acest lucru nu mai este cazul, deoarece versiunea ES6 a JavaScript implementează blocarea domeniului folosind noile cuvinte cheie let
și const
.
evaluare contextEdit
lipsa domeniului de aplicare al blocului înseamnă că variabilele definite în interiorul (de exemplu) A Pentru Buclă vor avea definiția lor „ridicată” în partea de sus a funcției de închidere. Evaluarea unei funcții care depinde de variabilele modificate de funcția exterioară (inclusiv prin iterație) poate fi dificilă. Putem vedea acest lucru fără o buclă dacă actualizăm o valoare între definirea și invocarea funcției.
var v, getValue;v = 1;getValue = function () { return v; };v = 2;getValue(); // 2
în timp ce rezultatul poate părea evident la actualizarea v
manual, acesta poate produce rezultate neintenționate atunci când getValue()
este definit în interiorul unei bucle.
în continuare funcția trecev
ca argument și este invocată imediat, păstrând contextul de execuție al funcției interioare.
var v, getValue;v = 1;getValue = (function (x) { return function () { return x; };})(v);v = 2;getValue(); // 1
Acest lucru este echivalent cu următorul cod:
var v, getValue;v = 1;function f(x) { return function () { return x; };};getValue = f(v);v = 2;getValue(); // 1
JavaScript eficient al lui David Herman conține un exemplu care ilustrează problemele contextului de evaluare din interiorul buclelor. În timp ce exemplul lui Herman este în mod deliberat complicat, acesta apare direct din aceeași lipsă de domeniu de bloc.
stabilirea variabilelor private și a accesoriiloredit
IIFEs sunt, de asemenea, utile pentru stabilirea metodelor private pentru funcții accesibile, expunând în același timp unele proprietăți pentru o utilizare ulterioară. Următorul exemplu vine din postarea lui Alman despre IIFEs.
// "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
dacă încercăm să accesăm counter.i
din mediul global, acesta va fi nedefinit, deoarece este inclus în funcția invocată și nu este o proprietate a counter
. De asemenea, dacă încercăm să accesăm i
, va rezulta o eroare, deoarece nu am declarat i
în mediul global.