Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

No need for IIFEs any more?

43 views
Skip to first unread message

RobG

unread,
Mar 13, 2018, 12:42:21 AM3/13/18
to
Since block scoped variables were introduced in ECMAScript 2015, it's been possible to implement the same "private variable" functionality as is available using the IIFE pattern.

E.g.

// Using an IIFE
var getNext = (function() {
var i = 0;
return function() {
return i++;
};
}

console.log(getNext()); // 0
console.log(getNext()); // 1

// Using block scope
{
let i = 0;
var getNext = function() {
return i++;
}
}

console.log(getNext()); // 0
console.log(getNext()); // 1

There are some quirks here:

- Function declarations inside blocks are available outside the block, but only in non–strict mode.
- Safari has a bug in non-strict mode in that if *getNext* uses a function declaration, the closure with *i* isn't preserved, so a reference error results when the function is called.
- Safari is inconsistent with other major browsers in non-strict mode where function declarations inside blocks are "hoisted", whereas in others they aren't.
- Variable declarations using *var* are available outside the block in both strict and non-strict mode, hence the use of a function expression so the code can be used in either mode (and to avoid the Safari bug).
- Using block+var+function expression means functions are only available after the statement that assigns them to the variable

Therefore it seems that the block+var+function expressions pattern (BVFE?) can be a replacement for IIFEs, as they provide provide consistent results across current implementations in either mode, though I haven't tested that widely.

So:

1. Are there any features of IIFEs that can't be easily replaced by a block?

2. Are there any quirks to be aware of (other than those noted above)?

3. Can blocks be used to replace IIFEs?


--
Rob

Michael Haufe (TNO)

unread,
Mar 13, 2018, 4:27:25 PM3/13/18
to
Why not use some other modern features such as lambdas and default parameters?

<script>
var getNext = ((i = 0) =>
() => i++
)();

`${getNext()},${getNext()}` /* 0,1 */
</script>

Joao Rodrigues

unread,
Mar 13, 2018, 5:43:05 PM3/13/18
to
On 13/03/2018 01:42, RobG wrote:
> Since block scoped variables were introduced in ECMAScript 2015,
> it's been possible to implement the same "private variable" functionality as
> is available using the IIFE pattern.

> [snip]

You may replace an IIFE with a block and a let or const declaration
(*don't use 'var' in this case*) or a module in ES6. There were some
examples of that in the book 'Exploring ES6', section 12.3.5, by Dr.
Axel Rauschmayer:

<http://exploringjs.com/es6/ch_callables.html#sec_iifes-in-es6>

There's also the possibility of using an Immediately-Invoked Arrow
Function (IIAF) in ES6. For example:

/*jshint esnext: true */
(() => {
// code.
})();

BTW, your getNext() function may be refactored to a Generator in ES6:

/*jshint esnext: true */
{
let gen = (function* idGen() {
let i = 0;
while(true) yield i++;
}());

console.log(gen.next()); // 0
console.log(gen.next()); // 1
console.log(gen.next()); // 3
}


--
Joao Rodrigues

RobG

unread,
Mar 16, 2018, 12:47:47 AM3/16/18
to
On Wednesday, March 14, 2018 at 6:27:25 AM UTC+10, Michael Haufe (TNO) wrote:
[...]
> Why not use some other modern features such as lambdas and default parameters?
>
> var getNext = ((i = 0) =>
> () => i++
> )();

Seems to me that's just an IIFE using newer syntax.

--
Rob

RobG

unread,
Mar 16, 2018, 12:54:42 AM3/16/18
to
On Wednesday, March 14, 2018 at 7:43:05 AM UTC+10, Joao Rodrigues wrote:
> On 13/03/2018 01:42, RobG wrote:
> > Since block scoped variables were introduced in ECMAScript 2015,
> > it's been possible to implement the same "private variable" functionality as
> > is available using the IIFE pattern.
>
> > [snip]
>
> You may replace an IIFE with a block and a let or const declaration
> (*don't use 'var' in this case*) or a module in ES6. There were some
> examples of that in the book 'Exploring ES6', section 12.3.5, by Dr.
> Axel Rauschmayer:
>
> <http://exploringjs.com/es6/ch_callables.html#sec_iifes-in-es6>

Thanks, I'll check it out.


> There's also the possibility of using an Immediately-Invoked Arrow
> Function (IIAF) in ES6. For example:
[...]

Yes, but that's just an IIFE using arrow function syntax. It also changes the behaviour of *this* in the function, so not a pattern that can be adopted for general replacement.

> BTW, your getNext() function may be refactored to a Generator in ES6:

Sure, it was just the simplest practical example I could think of. ;-)

--
Rob
0 new messages