+ 9

IIFEs: purpose and practicality in JS coding

I have searched the Q&A section and I have actually seen only one question about this topic here and the answer was a little general. Immediately Invoked Function Expressions seem to have a complicated syntax and I would like some help in understanding what their purpose is and how practical it is to use them. Is it worthwhile to use them whenever we code or is there a specific situation where they are applied? Thanks in advance!

11th Jul 2019, 3:05 AM
D.R.
D.R. - avatar
18 odpowiedzi
+ 13
In the past, there were no block-level lexical environment in JS. So programmers had to invent something. And what they did is called “immediately-invoked function expressions” (abbreviated as IIFE). That’s not a thing we should use nowadays, but you can find them in old scripts, so it’s better to understand them. (function() { var innerScoped = '4rontender'; }()); console.log(innerScoped ); // ReferenceError ECMAScript introduced the block scoped let and const, so instead of using an IIFE, we can have the following code: { let innerScoped = '4rontender'; } console.log(sinnerScoped); // ReferenceError What about IIFE: var myModule = (function() { // private variable, accessible only inside the IIFE var counter = 0; function increment() { counter++; } // publicly exposed logic return { increment: increment } }()); Instead of using this pattern, with ES6 we can use modules. Modules declare their own scope and variables created inside the module will not polute the global object: // myModule.js let counter = 0; export function increment() { counter++; } // logic.js import {increment} from 'myModule.js'; increment();
11th Jul 2019, 3:36 AM
Вап
+ 13
For safety use also ;(function() { alert("semocolon use too"); }());
11th Jul 2019, 4:26 AM
Николай Шаповаленко
Николай Шаповаленко - avatar
+ 13
Calviղ global pollution, bro👍😎
11th Jul 2019, 6:10 AM
Вап
+ 13
The good article from Flavio: https://flaviocopes.com/javascript-iife/
30th Jul 2019, 2:54 AM
Вап
+ 13
BroFarOps Didn't notice that you suggested the same article, sir🙏
30th Jul 2019, 4:53 AM
Вап
+ 12
The Function Expression is wrapped with parenthesis (function {...}), because when JavaScript meets "function" in the main code flow, it understands it as the start of a Function Declaration. But a Function Declaration must have a name. So, parentheses around the function is a trick to show JavaScript that the function is created in the context of another expression, and hence it’s a Function Expression: it needs no name and can be called immediately. There are other ways to tell JavaScript that we mean a Function Expression: // Ways to create IIFE (function() { alert("Parentheses around the function"); })(); (function() { alert("Parentheses around the whole thing"); }()); !function() { alert("Bitwise NOT operator starts the expression"); }(); +function() { alert("Unary plus starts the expression"); }(); P.S. I think tilda (~) will suit too. Maybe I am wrong, not sure... ~function() { alert("Tilda starts the expression"); }();
11th Jul 2019, 3:50 AM
Вап
+ 11
Read about design pattern "Module". Global pollution
11th Jul 2019, 3:12 AM
Вап
+ 9
Yeah. Block scoped variables are better approaches to work with inside functions and loops without shadow od doubt. IIFE can still be useful when you have a function like a init() and you want to initialize it right after the script runs. They are self invoked and automatically will trigger the function. You can write even more concise functions without a caller: //1) Without IIFE function init1() { console.log("Running this code 1"); } init1(); //requires a caller here //2) IIFE (function init2() { console.log("Running this code 2"); })(); //3) IIFE with arguments (function init3(go) { console.log(`Running this code 3 ${go}`); })(" - Go, go, go!"); //Output: //Running this code 1 //Running this code 2 //Running this code 3 - Go, go, go! I used this IIFE Syntax with arguments in this following JS DEMO code of mine. https://code.sololearn.com/WUOpSzOpmg3D/?ref=app
11th Jul 2019, 5:17 AM
Luis Febro 🇧🇷
Luis Febro 🇧🇷 - avatar
+ 6
Oh, awesome. So, basically, it's a good thing to know when we come across old code, but let and const sort of made them obsolete? That will be an awesome help. Can you think of anything that has to stay in the IIFE realm and cannot be expressed with these? Thanks a lot, guys!!! Really helpful! 😁 Just to make sure I understood, 4rontender, these examples of IIFE functions you gave, they were useless per se, since there is nothing inside them that actually deserved protecting, just alert commands, right?
11th Jul 2019, 4:17 AM
D.R.
D.R. - avatar
+ 6
4rontender glad you liked my suggested article
30th Jul 2019, 3:22 AM
BroFar
BroFar - avatar
+ 5
I'd actually like to know your opinion a bit, 4rontender and BroFarOps, as to the real need of using these. I mean, why wouldn't one want every function to be written the same way if it's such a lifesaver when it comes to protecting what's inside. Also, that seems a sort of complex syntax to be writing over and over and my question goes a little more in this direction. Thank you for answering so fast, guys. Really appreciated it.
11th Jul 2019, 3:27 AM
D.R.
D.R. - avatar
+ 5
part 2 .. continue.. To protect the variables and functions from external execution, we need to add Function Expression (FE) to the module. By adding function() { // Module codes here } for 1sec timer: function() { var i=0; function runTimerOnce() { setInterval(update, 1000); } function update() { console.log(i++); } runTimerOnce(); } ); **** To make sure the module can be Immediately Invoked (II) only once time. We add ;(FE)(); ;( function() { // Module codes here } )(); **** The overall concept is called Immediately Invoked Function Expression (IIFE), which apply to a module to protect their variables and functions, and ensure module only immediately invoked once. To apply IIFE to the 1 sec timer i mentioned previously: ;( function() { var i=0; function runTimerOnce() { setInterval(update, 1000); } function update() { console.log(i++); } runTimerOnce(); } )(); https://code.sololearn.com/WXtgNXdMj9V1/?ref=app
11th Jul 2019, 5:47 AM
Calviղ
Calviղ - avatar
+ 4
think in terms that each area is lock specific and each set (/* function*/) is controlled smoother from one level to the next... as flaviocopes explained: "they don't pollute the global object, and they are a simple way to isolate variables declarations"
11th Jul 2019, 3:37 AM
BroFar
BroFar - avatar
+ 4
4rontender that is interesting to know because we have seen many sites still structured with as you say old script structuring in present day webs _ however by maybe older developers whom are familiar with those iife scopes
11th Jul 2019, 3:45 AM
BroFar
BroFar - avatar
+ 4
Let say we have a module which increment and update i variable on console.log every second. var i=0; function runTimerOnce() { setInterval(update, 1000); } function update() { console.log(i++); } runTimerOnce(); If we release this module for other developer to further developing their codes. The developers can reset i variable by assign i=<any number> or use i variable as input of other function. The developers can also call function runTimerOnce() multiple times, which eventually create more than one running timers which screw up the one second increment operation. How can we use protect the variable i, from external update (or read/write)? How can I ensure that only one time of function runTimerOnce() execution? part 1.... to be continue...
11th Jul 2019, 5:33 AM
Calviղ
Calviղ - avatar
+ 2
4rontender no problem 👍 good to see same thoughts at work...
30th Jul 2019, 5:21 AM
BroFar
BroFar - avatar