0

I still a bit confused with those Immediate Invoked Function Expression. I got the scope closure (I've read Crockford's book), but then @plalx kindly wrote me this example for another doubt i had (jsfiddle linked at the end) using IIFE. And that made a bit confused again, here how I'm thinking.

In Java one would think:

type doSome(type input){
do_stuff
return same type
};

then later

doSome(data);

so in js I could do just the same, right?

function doSome(input){
do_stuff;
return someThing;
}

and latter:

doSome(data);

or with an IIFE much more used:

var doSome = (function(data){
do_stuff;
return something
})();

and latter:

doSome(data);

Am I correct so far?

So my question is: Why use IIFE instead of the other way in this case? both codes that raised this doubt are in jsfiddle:

http://jsfiddle.net/Victornpb/PT6Xc/7/

http://jsfiddle.net/PT6Xc/8/

Community
  • 1
  • 1
v.k.
  • 2,826
  • 2
  • 20
  • 29
  • The IIFE will be immediately fired so its different from the function above it. An IIFE is a function you want to execute immediately so its the same as calling `function init(){/**/}; init();` with `(function(/**/){})()` – megawac Oct 17 '13 at 00:07
  • 1
    If the thing you return in the IIFE is a function then you can `doSome(data)` otherwise it's similar to setting doSome to a value. – asafreedman Oct 17 '13 at 00:09
  • @asafreedman That's makes sense, plalx did that, returned a function! Now i see :) thanks a lot. – v.k. Oct 17 '13 at 00:12

2 Answers2

2

IIFEs are useful for using closures to hold references to "private" variables. They might be used to prevent others from modifying values you want to protect, or to hold the result of a computation that only needs to be done once (or occasionally) but is frequently used by the function.

e.g. to get the text of an element you might write:

function getText(el) {

  if (typeof el.textContent == 'string') {
    return el.textContent;

  } else if (typeof el.innerText == 'string') {
    return el.innerText;
  }
}

but to avoid having to do the test every time, an IIFE can be used and the test performed just once:

var getText = (function() {
  var d = document.createElement('div');

  if (typeof div.textContent == 'string') {
    return function (el) {
      return el.textContent;
    };

  } else if (typeof div.innerText == 'string') {
    return function (el) {
      return el.innerText;
    };
  }
}());

So the test is only performed once. You can also keep a reference to the global object using a similar strategy:

var someFn = (function (global) {

    // in here, you are certain that global references the global object

    return function() {
      // and in here too
    };

// And here's where it comes from
}(this));
RobG
  • 142,382
  • 31
  • 172
  • 209
  • Thanks, if I understood that correctly you would call the IIFE version by calling `getText(element)` right? – v.k. Oct 17 '13 at 00:17
2

The primary difference between those two example is how often the body of the function is evaluated.

In this example: http://jsfiddle.net/Victornpb/PT6Xc/7/, with the IIFE, the code inside is only evaluated once and the function is returned. When you run the function via

document.body.innerHTML = deaccentuate(s);

It only executes the body of the function that was returned and not the statements that come prior to it.

In the other example: http://jsfiddle.net/PT6Xc/8/

The entire body of the function is evaluated every time you run the deaccentuate(s) function.

document.body.innerHTML = deaccentuate(s);

So, if you have some heavy operation that you just want to perform once at runtime, or like @RobG said for private members, use the IIFE in this case.

You can verify this by adding console.log("whatever") to the top of both examples to verify.

http://jsfiddle.net/PT6Xc/9/ -> goes with /7/

and

http://jsfiddle.net/PT6Xc/10/ -> goes with /8/

asafreedman
  • 572
  • 4
  • 10
  • This is corretct as well, I'd like to be able accept both answer, but i can't,so double thanks! – v.k. Oct 17 '13 at 00:51