Will Const and Let Make the Iife Pattern Unnecessary

Will const and let make the IIFE pattern unnecessary?

Yes, blocks are going to replace IEFEs, as soon as block-scoped declarations (functions, let/const/class) become widely adopted. You need a scope, e.g. for a closure? Here you have a block, be it a loop body or just part of a statement list.

However, there is still one application of IEFEs that blocks cannot replace: the module pattern. Blocks don't have return values, and mutating higher-scoped variables is ugly, so we will still see function expressions in the creation of objects that need private state:

const example = (() => {

return …;
}());

Can I drop IIFE when I have const inside function in JavaScript

The fact that OTHER_FUNCTION_RESULT is declared as const doesn't mean it's only ever called once:

function callOften(){  const test = init(); // This is a `const`, but does it get called more often?}
function init(){ console.log('Init Called'); return 1;}
callOften();callOften();callOften();

Are JavaScript iifes (Immediately-invoked function expressions) still relevant?

Pretty much all the common reasons for using an IIFE in my code have been replaced with block-scoped variables.

The ONE use I have seen in real code is to simulate top-level await:

(async function() {
try {
const data1 = await something1();
const data2 = await something2(data1);
...
} catch(e) {
...
}
})();

The remaining reasons I see for an IIFE are when you want the advantages of a function such as using return or throw to stop execution of a defined portion of the remaining code (without nesting in an if) or when you want to call something recursively. But, of course, you could get all of those advantages with a locally scoped named function too.

But, if the code in your function benefits heavily from accessing parent scoped variables, then it really wants to be inline and that creates a possible reason for an IIFE to combine the advantages of being in a separate function with inline access to parent scope.

Now, in reality, most/all of these cases can also be solved with a little refactoring to either define the named function in the local scope (so it still has access to parent scoped variables) or just pass things from the parent scope to a named function so it has access to them that way and, in fact, that's what we all do in other languages. The only cost to that is one more local function name (which can even be locally scoped if you want to hide it).

do we still use iife in es6+

IIFEs were often used with the Module Pattern in JS to limit what a module would expose to the caller. We now have much better options for scoping, modules and intelligent bundling of assets, so you will rarely see it used anymore.

In my experience, it is not that we have a new way of doing it, it is just that the use-case for it has almost vanished. That being said, if you find yourself in the rare situation where it is needed, it is still perfectly valid.

Do we need to wrap ES6 code in an IIFE?

If you're using modules, there's no need to use IIFE (that's how this "wrapper" is called), because all variables have scope limited to the module.

However, there still are some cases when you want to separate one part of the code from another, and then you can use IIFE.

Of course if you're using let or const, you can use a block statement instead of IIFE:

{
let something = 1;
const somethingElse = 2;
}
console.log(something); // ReferenceError: something is not defined

See related question on Programmers.SE: How far should encapsulation in JavaScript go?.

Is there any difference between using IIFY(Immediately-Invoked Function Expression) and {...}

Using a block and let will have the same effect, but be more efficient than the IIFE in this case.

The IIFE pattern predates let being added to the JavaScript language so it is more common (and supported in IE10 and earlier).

What is the (function() { } )() construct in JavaScript?

It’s an Immediately-Invoked Function Expression, or IIFE for short. It executes immediately after it’s created.

It has nothing to do with any event-handler for any events (such as document.onload).

Consider the part within the first pair of parentheses: (function(){})();....it is a regular function expression. Then look at the last pair (function(){})();, this is normally added to an expression to call a function; in this case, our prior expression.

This pattern is often used when trying to avoid polluting the global namespace, because all the variables used inside the IIFE (like in any other normal function) are not visible outside its scope.

This is why, maybe, you confused this construction with an event-handler for window.onload, because it’s often used as this:

(function(){
// all your code here
var foo = function() {};
window.onload = foo;
// ...
})();
// foo is unreachable here (it’s undefined)

Correction suggested by Guffa:

The function is executed right after it's created, not after it is parsed. The entire script block is parsed before any code in it is executed. Also, parsing code doesn't automatically mean that it's executed, if for example the IIFE is inside a function then it won't be executed until the function is called.

Update
Since this is a pretty popular topic, it's worth mentioning that IIFE's can also be written with ES6's arrow function (like Gajus has pointed out in a comment) :

((foo) => {
// do something with foo here foo
})('foo value')

Javascript iife functions

In that function looks like is just to show you how to work the IIFE(the parentheses at the end of the function) that parenthesis is to auto-execute the function, the use is if you want to execute a function when this load you can add the "()" at the end or "+" at the beginning of the clause "function" like this "+function" to see more in details check the following link:

Immediately-Invoked Function Expression (IIFE)

Does the module pattern require the use of an IIFE?

In JavaScript ECMAScript 5 and older, an IIFE, or immediately-invoked function expression, was necessary to create a function scope that prevented var declarations from polluting the global namespace when implementing the revealing module pattern.

(function () {
var foo = 'bar'
var counter = 0

this.someGlobalModule = function () {
counter++

return { foo: foo, counter: counter }
}
}.call(this))
// this === window at top-level in browser

// no access to function-scope foo or counter, only someGlobalModule()
var value = someGlobalModule()

// value.foo === 'bar'
// value.counter === 1

Now with JavaScript ECMAScript 6, the introduction of const and let declarations allow block-scope variables, as opposed to function-scope, so you can simply use a block-scope to implement the revealing module pattern:

{
const foo = 'bar'
let counter = 0

// this === window at top-level in browser
this.someGlobalModule = () => {
counter++

return { foo, counter }
}
}

// no access to block-scope foo or counter, only someGlobalModule()
let value = someGlobalModule()

// value.foo === 'bar'
// value.counter === 1


Related Topics



Leave a reply



Submit