Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.javascript > #34771 > unrolled thread
| Started by | RobG <rgqld@iinet.net.au> |
|---|---|
| First post | 2018-03-12 21:42 -0700 |
| Last post | 2018-03-15 21:54 -0700 |
| Articles | 5 — 3 participants |
Back to article view | Back to comp.lang.javascript
No need for IIFEs any more? RobG <rgqld@iinet.net.au> - 2018-03-12 21:42 -0700
Re: No need for IIFEs any more? "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2018-03-13 13:27 -0700
Re: No need for IIFEs any more? RobG <rgqld@iinet.net.au> - 2018-03-15 21:47 -0700
Re: No need for IIFEs any more? Joao Rodrigues <groups_jr-1@yahoo.com.br> - 2018-03-13 18:43 -0300
Re: No need for IIFEs any more? RobG <rgqld@iinet.net.au> - 2018-03-15 21:54 -0700
| From | RobG <rgqld@iinet.net.au> |
|---|---|
| Date | 2018-03-12 21:42 -0700 |
| Subject | No need for IIFEs any more? |
| Message-ID | <1c492da9-76d8-4c70-8c73-1c6e2f8baa23@googlegroups.com> |
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
[toc] | [next] | [standalone]
| From | "Michael Haufe (TNO)" <tno@thenewobjective.com> |
|---|---|
| Date | 2018-03-13 13:27 -0700 |
| Message-ID | <8356a1cf-b575-4e12-bd59-070c0331b5c2@googlegroups.com> |
| In reply to | #34771 |
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.
>
> 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?
>
Why not use some other modern features such as lambdas and default parameters?
<script>
var getNext = ((i = 0) =>
() => i++
)();
`${getNext()},${getNext()}` /* 0,1 */
</script>
[toc] | [prev] | [next] | [standalone]
| From | RobG <rgqld@iinet.net.au> |
|---|---|
| Date | 2018-03-15 21:47 -0700 |
| Message-ID | <638c75ad-c2f8-4582-8ac2-310dc0c7ec7d@googlegroups.com> |
| In reply to | #34775 |
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
[toc] | [prev] | [next] | [standalone]
| From | Joao Rodrigues <groups_jr-1@yahoo.com.br> |
|---|---|
| Date | 2018-03-13 18:43 -0300 |
| Message-ID | <p89gkv$142r$1@gioia.aioe.org> |
| In reply to | #34771 |
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
[toc] | [prev] | [next] | [standalone]
| From | RobG <rgqld@iinet.net.au> |
|---|---|
| Date | 2018-03-15 21:54 -0700 |
| Message-ID | <87922ffc-6076-413b-b671-07e546812b3f@googlegroups.com> |
| In reply to | #34776 |
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
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.javascript
csiph-web