Нужно ли нам оборачивать код ES6 в IIFE?

В ES5 написание такого кода считалось хорошей практикой:

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

Но в ES6 переменные, созданные с ключевым словом let, не привязываются к объекту window.

Итак, есть ли сейчас необходимость писать наш код в IIFE, или у него все еще есть какие-то цели, о которых я не слышал?


person Vyacheslav Palamar    schedule 23.05.2016    source источник
comment
Связано: Пространство имен с IIFE в ES6?   -  person Michał Perłakowski    schedule 23.05.2016
comment
См. также Сделает ли const и let шаблон IIFE ненужным?   -  person Bergi    schedule 23.05.2016
comment
переменные, созданные с помощью ключевого слова let, не привязаны к объекту window, но они остаются глобальными. Поэтому, если вы пишете сценарии, вам нужно поместить их в блок или IIFE.   -  person Bergi    schedule 23.05.2016
comment
@Bergi Разве этот вопрос не дублирует вопрос, который вы связали?   -  person Michał Perłakowski    schedule 23.05.2016
comment
@Gothdo: Возможно, но я не был уверен, делает ли акцент на const+let их разными, поэтому я не хотел обманывать. Не стесняйтесь отдать свой голос; и если ОП согласится, я с радостью закрою.   -  person Bergi    schedule 23.05.2016


Ответы (2)


Если вы используете модули, нет необходимости использовать IIFE (так называется эта «обертка»), потому что все переменные имеют область действия, ограниченную модулем.

Однако все же бывают случаи, когда хочется отделить одну часть кода от другой, и тогда можно использовать IIFE.

Конечно, если вы используете let или const, вы можете использовать оператор блока вместо IIFE:

{
  let something = 1;
  const somethingElse = 2;
}
console.log(something); // ReferenceError: something is not defined

См. соответствующий вопрос на Programmers.SE: Как далеко должна зайти инкапсуляция в JavaScript? .

person Michał Perłakowski    schedule 23.05.2016
comment
Насколько я понимаю, класс ES6 по существу предлагает ту же или почти такую ​​же функциональность, что и IIFE. Это правильно? - person lux; 23.05.2016
comment
@lux Нет, классы ES6 разные. - person Michał Perłakowski; 23.05.2016
comment
this инкапсулирован в класс, не так ли? - person lux; 23.05.2016
comment
@lux: Нет, классы ничего не инкапсулируют. Они так же хороши, как литерал объекта с определениями методов. - person Bergi; 23.05.2016
comment
@Bergi Спасибо, кажется, это просто синтаксический сахар (поскольку это просто объект). Гав. - person lux; 23.05.2016

Теперь это не проблема, но я бы сказал, что для этой общей идеи все еще есть причина.

Теоретически, скажем, какая-то сторонняя библиотека может написать такой код:

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

Теперь, если вы попытаетесь создать свою собственную переменную count в той же области видимости, вы получите сообщение об ошибке:

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

// Your code
let count = 1;

Однако вы можете сделать код чище, используя настоящие блоки вместо IIFE.

// 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());
}

В будущем вы сможете инкапсулировать свой код в модули, которые будут иметь свою собственную область видимости, и вам не нужно будет оборачивать свой код в IIFE или блок.

person Mike Cluck    schedule 23.05.2016
comment
Как на это влияет лексическая область видимости в классах ES6? - person lux; 23.05.2016
comment
@lux То же, что и в последнем примере. Любые переменные, объявленные в другой области (включая методы в классе), будут скрывать переменные во внешней области без попытки переопределить исходную переменную. Точно так же, если вы попытаетесь объявить класс с именем X в области, в которой уже есть другой класс или любая другая переменная с именем X, вы столкнетесь с ошибкой переопределения. - person Mike Cluck; 23.05.2016