Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #34771 > unrolled thread

No need for IIFEs any more?

Started byRobG <rgqld@iinet.net.au>
First post2018-03-12 21:42 -0700
Last post2018-03-15 21:54 -0700
Articles 5 — 3 participants

Back to article view | Back to comp.lang.javascript


Contents

  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

#34771 — No need for IIFEs any more?

FromRobG <rgqld@iinet.net.au>
Date2018-03-12 21:42 -0700
SubjectNo 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]


#34775

From"Michael Haufe (TNO)" <tno@thenewobjective.com>
Date2018-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]


#34786

FromRobG <rgqld@iinet.net.au>
Date2018-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]


#34776

FromJoao Rodrigues <groups_jr-1@yahoo.com.br>
Date2018-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]


#34787

FromRobG <rgqld@iinet.net.au>
Date2018-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