Do we need to wrap ES6 code in an IIFE?
Asked Answered
M

2

21

In ES5, writing such code has been considered as good practice:

(function () {
    //some magic
})();

But in ES6 variables created with let keyword are not attached to window object.

So, is there any need now in writing our code in an IIFE, or it still has some purposes I haven't heard about?

Maupassant answered 23/5, 2016 at 19:45 Comment(5)
Related: Namespacing with IIFE in ES6?Carollcarolle
See also Will const and let make the IIFE pattern unnecessary?Saberhagen
"variables created with let keyword are not attached to window object" - but they are still global. So if you are writing scripts, you will need to put them in a block or an IIFE.Saberhagen
@Saberhagen Isn't this question a duplicate of the question you linked?Carollcarolle
@Gothdo: Maybe, but I wasn't sure whether the focus on const+let does make them different, so I didn't want to dupe-hammer. Feel free to cast your vote; and if the OP agrees I'll happily close.Saberhagen
J
11

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?.

Jacklight answered 23/5, 2016 at 19:52 Comment(6)
As I understand it, the ES6 class essentially offers the same, or near-the-same, functionality as the IIFE. Is that correct?Fairish
@Fairish No, ES6 classes are different.Carollcarolle
this is encapsulated in the class, no?Fairish
@Fairish This question is not about classes. If you want to discuss that, ask another question or ask me in chat.Carollcarolle
@lux: No, classes encapsulate nothing. They're as good as an object literal with method defintions.Saberhagen
@Saberhagen Thanks, just syntactic sugar it seems (since its just an obj lit). Woof.Fairish
L
5

It is less of a problem now but I'd argue there's still a reason for that general idea.

Theoretically, it is possible for, say, some third-party library to write code like this following:

let count = 0;
function getCount() {
  return count++;
}

Now, if you tried to create your own count variable in the same scope, you'd get an error:

// 3rd-party
let count = 0;
function getCount() {
  return count++;
}

// Your code
let count = 1;

However, you can make the code cleaner by using actual blocks instead of IIFEs.

// Still bad 3rd party
let count = 0;
function getCount() {
  return count++;
}

// Your code
{
  let count = 10;
  console.log(count);
  console.log(getCount());
  console.log(count);
  console.log(getCount());
}

In the future, you should be able to encapsulate your code in modules which will have their own scope and you won't need to wrap your code in an IIFE or a block.

Libelous answered 23/5, 2016 at 19:54 Comment(2)
How does lexical scoping in ES6 classes affect this?Fairish
@Fairish Same as it does in the last example. Any variables declared in a different scope (including methods in a class) will shadow variables in an outer scope without attempting to redefine the original variable. Likewise, if you attempt to declare a class with the name X in a scope which already has another class, or any other variable, named X then you'll run into a redefinition error.Libelous

© 2022 - 2024 — McMap. All rights reserved.