Content deleted Content added
Citations to templates; futureproof citations; citations outside punctuation; harmonize dates, spacing; format ISBNs |
m Added additional way to pass variables into IIFE |
||
(45 intermediate revisions by 31 users not shown) | |||
Line 1:
{{Short description|Javascript design pattern}}
An '''immediately
Immediately invoked function expressions can be used to avoid [[JavaScript syntax#Scoping and hoisting|variable hoisting]] from within blocks, protecting against polluting the [[Global variable|global environment]] and simultaneously allowing public access to methods while retaining privacy for variables defined within the function. In other words, it wraps functions and variables, keeping them out of the global scope and giving them a local scope.
== Usage ==
Immediately
<syntaxhighlight lang="JavaScript">
(function () { /* ... */ })();
(function () { /* ... */ }());
(() => { /* ... */ })(); // With ES6 arrow functions (though parentheses only allowed on outside)
</syntaxhighlight>▼
!function () { /* ... */ }();▼
</syntaxhighlight>
In contexts where an expression is expected, wrapping in parentheses is not necessary:
<syntaxhighlight lang="
true && function () { /* ... */ }();
0, function () { /* ... */ }();
Line 27 ⟶ 21:
Passing variables into the scope is done as follows:
<syntaxhighlight lang="
(function(a, b) { /* ... */ })("hello", "world");
</syntaxhighlight>
An initial parenthesis is one case where the [[automatic semicolon insertion]] (ASI) in JavaScript can cause problems; the expression is instead interpreted as a call to the last term on the preceding line. In some styles that omit optional semicolons, the semicolon is placed ''in front'' of the parenthesis, and is known as a [[defensive semicolon]].<ref name=inimino>{{cite web |url=http://inimino.org/~inimino/blog/javascript_semicolons |title=JavaScript Semicolon Insertion: Everything you need to know |date=28 May 2010 |archive-url=https://web.archive.org/web/20171002224530/http://inimino.org/~inimino/blog/javascript_semicolons |archive-date=2 October 2017 |
<syntaxhighlight lang="JavaScript">
a = b + c
Line 40 ⟶ 35:
...to avoid being parsed as <code>c()</code>.
==
The key to understanding design patterns such as
// Before ES6: Creating a scope using an IIFE
var foo = 1;
var bar = 2;
(function(){
var foo = 3; // shadows the outer `foo`
bar = 4; // overwrites the outer `bar`
})();
console.log(foo, bar); // 1 4
// Since ES6: Creating a scope using curly brackets in combination with let and const
const foo = 1;
let bar = 2;
{
const foo = 3; // shadows the outer `foo`
bar = 4; // overwrites the outer `bar`
}
console.log(foo, bar); // 1 4
▲</syntaxhighlight>
=== Evaluation context ===
A lack of block scope means that variables defined inside
<syntaxhighlight lang="
v = 1;
getValue = function () { return v; };
Line 56 ⟶ 70:
While the result may seem obvious when updating <code>v</code> manually, it can produce unintended results when <code>getValue()</code> is defined inside a loop.
Hereafter the function passes <code>v</code> as an argument and is invoked immediately, preserving the inner function's execution context.<ref name=JQ>{{cite book |
<syntaxhighlight lang="
v = 1;
getValue = (function (x) {
Line 70 ⟶ 84:
This is equivalent to the following code:
<syntaxhighlight lang="
v = 1;
function f(x) {
Line 81 ⟶ 95:
getValue(); // 1
</syntaxhighlight>
=== Establishing private variables and accessors ===
IIFEs are also useful for establishing private methods for accessible functions while still exposing some properties for later use.<ref>{{cite book |last=Rettig |first=Pascal |title=Professional HTML5 Mobile Game Development |year=2012 |publisher=John Wiley & Sons |isbn=978-1-118-30133-3 |page=145}}</ref> The following example comes from Alman's post on IIFEs.<ref name=Alman/>
<syntaxhighlight lang="
// "counter" is a function that returns an object with properties, which in this case are functions.
return {
Line 115 ⟶ 127:
== Terminology ==
Originally known as a "self-executing anonymous function",<ref>{{cite book |last=Resig |first=John |title=Pro JavaScript Techniques |year=2006 |publisher=Apress |isbn=978-1-4302-0283-7 |page=29}}</ref> Ben Alman later introduced the current term IIFE as a more semantically accurate name for the idiom, shortly after its discussion arose on comp.lang.javascript.<ref name=Alman/><ref name=Osmani>{{cite book |last=Osmani |first=Addy |title=Learning JavaScript Design Patterns |year=2012 |publisher=O'Reilly |isbn=978-1-4493-3487-1 |page=206}}</ref><ref>{{cite news |last=Baagoe |first=Johannes |title=Closing parenthesis in function's definition followed by its call |url=https://groups.google.com/forum/#!topic/comp.lang.javascript/tjVn1NjGDN8%5B1-25%5D |accessdate=19 April 2010}}</ref>
"Immediately-invoked function expression" as a term describes a design pattern that has also been referred to as a "self-executing anonymous function".<ref name=Alman/><ref name=Enlighten/> However, immediately-invoked functions do not need to be anonymous, and [[ECMAScript]]{{nbsp}}5's strict mode forbids <code>arguments.callee</code>,<ref>{{cite web |title=Strict mode |url=https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/Strict_mode#Making_eval_and_arguments_simpler |work=Mozilla JavaScript Reference |publisher=Mozilla Developer Network |accessdate=4 February 2013}}</ref> making the latter term less accurate.<ref name=Osmani/><ref name=JQ/>▼
▲
== See also ==
*[[Evaluation strategy]]
== References ==
Line 124 ⟶ 139:
== External links ==
* {{cite web |title=Functions and function scope |url=https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope |work=Mozilla JavaScript Reference |publisher=Mozilla Developer Network |accessdate=4 February 2013}}
[[Category:JavaScript]]
[[Category:Programming language concepts]]
|