Immediately invoked function expression: Difference between revisions

Content deleted Content added
Citation bot (talk | contribs)
Add: date, authors 1-1. Removed parameters. Some additions/deletions were parameter name changes. | Use this bot. Report bugs. | Suggested by Superegz | Category:Programming language concepts‎ | #UCB_Category 12/23
MOD31P (talk | contribs)
m Added additional way to pass variables into IIFE
 
(14 intermediate revisions by 6 users not shown)
Line 1:
{{Short description|Javascript design pattern}}
 
An '''immediately invoked function expression''' (or '''IIFE''', pronounced "iffy", [[International Phonetic Alphabet|IPA]] /ˈɪf.i/) is a [[Programming idiom|programming language idiom]] which produces a [[scope (computer science)|lexical scope]] using [[function scoping]]. It was popular in [[JavaScript]]<ref name="Alman">{{cite web|url=http://benalman.com/news/2010/11/immediately-invoked-function-expression/|title=Immediately Invoked Function Expressions|last=Alman|first=Ben|date=15 November 2010|website=|url-status=live|archive-url=https://web.archive.org/web/20171201033208/http://benalman.com/news/2010/11/immediately-invoked-function-expression/|archive-date=1 December 2017|accessdate=18 January 2019}}</ref> as a method toof supportsupporting [[modular programming]] before the introduction of more standardized solutions such as [[CommonJS]] and [[ECMAScript#6th Edition – ECMAScript 2015|ES modules]].<ref>{{cite web |last1=McGinnis |first1=Tyler |title=JavaScript Modules: From IIFEs to CommonJS to ES6 Modules |url=https://ui.dev/javascript-modules-iifes-commonjs-esmodules/ |website=ui.dev |access-date=18 August 2021 |language=en |date=15 January 2019}}</ref>
 
Immediately invoked function expressions can be used to avoid [[JavaScript syntax#Scoping and hoisting|variable hoisting]] from within blocks, protectprotecting against polluting the [[Global variable|global environment]] and simultaneously allowallowing 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 ==
Line 11:
(function () { /* ... */ }());
(() => { /* ... */ })(); // With ES6 arrow functions (though parentheses only allowed on outside)
</syntaxhighlight>
 
There are other ways to enforce a function expression:{{cn|date=September 2022}}
<syntaxhighlight lang="JavaScript">
!function () { /* ... */ }();
~function () { /* ... */ }();
-function () { /* ... */ }();
+function () { /* ... */ }();
void function () { /* ... */ }();
delete function () { /* ... */ }();
typeof function () { /* ... */ }();
await function () { /* ... */ }();
</syntaxhighlight>
 
Line 33 ⟶ 21:
 
Passing variables into the scope is done as follows:
<syntaxhighlight lang="JavaScriptjavascript">
(function(a, b) { /* ... */ })("hello", "world");
!(function (a="hello", b="world") { /* ... */ })(); //also works
</syntaxhighlight>
 
Line 47 ⟶ 36:
 
==Examples==
The key to understanding design patterns such as IIFE is to realize that prior to ES6, JavaScript only featured [[Scope (computer science)#Function scope|function scope]] (thus lacking [[Scope (computer science)#Block scope|block scope]]), passing [[Call_by_reference|values by reference]] inside [[Closure (computer science)|closure]]s.<ref>{{cite book |last=Haverbeke |first=Marijn |title=Eloquent JavaScript |year=2011 |publisher=No Starch Press |isbn=978-1-59327-282-1 |pages=29–30}}</ref> This is no longer the case, as the ES6 version of JavaScript implements block scoping using the new <code>let</code> and <code>const</code> keywords.<ref>ECMAScript{{cite 6:web New|last1=Orendorff Features|first1=Jason |title=ES6 In Depth: Overviewlet &and Comparison,const [http|url=https://es6-featureshacks.mozilla.org/#BlockScopedVariables Block2015/07/es6-Scopedin-depth-let-and-const/ Variables|website=Mozilla Hacks – the Web developer blog |publisher=[[Mozilla]] |access-date=16 October 2024 |date=31 Jul 2015}}</ref><syntaxhighlight lang="javascript">
// 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 ===