22

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?

Michał Perłakowski
  • 88,409
  • 26
  • 156
  • 177
  • Related: [Namespacing with IIFE in ES6?](http://stackoverflow.com/questions/32746615/namespacing-with-iife-in-es6) – Michał Perłakowski May 23 '16 at 19:56
  • 1
    See also [Will const and let make the IIFE pattern unnecessary?](http://stackoverflow.com/q/33534485/1048572) – Bergi May 23 '16 at 20:04
  • "*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. – Bergi May 23 '16 at 20:05
  • @Bergi Isn't this question a duplicate of the question you linked? – Michał Perłakowski May 23 '16 at 20:07
  • 1
    @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. – Bergi May 23 '16 at 20:09

2 Answers2

12

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

Community
  • 1
  • 1
Michał Perłakowski
  • 88,409
  • 26
  • 156
  • 177
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.

Mike Cluck
  • 31,869
  • 13
  • 80
  • 91
  • How does lexical scoping in ES6 classes affect this? – lux May 23 '16 at 19:57
  • @lux 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. – Mike Cluck May 23 '16 at 20:03