Как немедленный вызов IIFE предотвращает загрязнение глобальной области видимости?

В уроке Udacity о немедленно вызываемых функциональных выражениях (относительно предоставленного фрагмента кода) говорится:

Возвращаемая функция закрывает (т. е. захватывает) переменную hi. Это позволяет myFunction поддерживать частное, изменяемое состояние, доступ к которому вне функции невозможен! Более того: поскольку выраженная функция вызывается немедленно, IIFE красиво упаковывает код, чтобы мы не загрязняли глобальную область видимости.

Я изо всех сил пытаюсь понять, какое непосредственное отношение к вызову анонимной функции имеет к предотвращению того, чтобы переменная hi «загрязняла глобальную область», и поскольку hi уже определена в функции, разве она уже не находится в локальной/частной области?

const myFunction = (
  function () {
    const hi = 'Hi!';
    return function () {
      console.log(hi);
    }
  }
)();

person nCardot    schedule 20.06.2018    source источник
comment
Дело в том, чтобы не допустить, чтобы hi было доступно из глобальной области видимости, и создать еще одно имя, с которым не может возникнуть конфликт.   -  person Patrick Roberts    schedule 20.06.2018
comment
Возможный дубликат шаблона проектирования JavaScript: разница между шаблоном модуля и раскрытие шаблона модуля?   -  person Patrick Roberts    schedule 20.06.2018
comment
Если бы вы не вызвали его немедленно, вам пришлось бы дать ему имя, загрязняя внешнюю область видимости.   -  person melpomene    schedule 20.06.2018
comment
в основном myFunction = function () { console.log(hi) }, потому что это результат iife, но если вы не используете iife, вам придется объявить hi во внешней области. Если вы сделаете это в самом высоком масштабе, вы получите hi в своем объекте window или global (в зависимости от того, что у вас есть), тем самым загрязняя его.   -  person apokryfos    schedule 20.06.2018
comment
Пока переменная находится внутри блока (в случае с let или const) или функции (в случае с автомобилем), она не загрязняет глобальную область видимости.   -  person nCardot    schedule 21.06.2018


Ответы (2)


В современном JavaScript у вас есть let и блочная область (и я почти уверен, что const тоже имеет блочную область), поэтому вы можете просто сделать это:

let myFunction;
{
    let hi = 'Hi!';
    myFunction = function () {
        console.log(hi);
    };
}

Это создает myFunction без утечки hi в окружающую область.

В традиционном JavaScript, где у вас есть только var и область действия функции, вы можете сделать это:

var myFunction;
function a_private_scope() {
    var hi = 'Hi!';
    myFunction = function () {
        console.log(hi);
    };
}
a_private_scope();

a_private_scope ограничивает область видимости hi, но (это объявление функции) ее нужно вызывать явно, и мы по-прежнему пропускаем имя в окружающую область видимости (на этот раз это a_private_scope, имя функции-служащей-как- объем).

Используя выражение функции и немедленно вызывая ее, мы избегаем загрязнения второго имени:

var myFunction;
(function () {
    var hi = 'Hi!';
    myFunction = function () {
        console.log(hi);
    };
})();

Теперь во внешней области определено только myFunction. Анонимная функция, которая служит областью действия для hi, не имеет имени, которым она могла бы загрязнить окружающую область.

Наконец, мы можем немного почистить его, используя возвращаемые значения, поэтому нам не нужно упоминать myFunction дважды:

var myFunction = function () {
    var hi = 'Hi!';
    return function () {
        console.log(hi);
    };
}();

(Это также избавляет нас от пары ( ), потому что ключевое слово function больше не появляется в начале оператора.)

person melpomene    schedule 20.06.2018

Как немедленный вызов IIFE предотвращает загрязнение глобальной области видимости?

Это не так.

Будучи функцией, она не загрязняет глобальную область видимости.

Переменные, объявленные внутри функции, существуют только внутри этой функции.

person Community    schedule 20.06.2018
comment
Им зачем нужна жизнь? Мы можем просто использовать обычные функции? Почему говорят, что жизнь предотвращает загрязнение глобального масштаба? - person Kumar Manish; 08.07.2018
comment
Вам не нужен IIFE. Вы можете использовать обычную функцию (но вам придется вызывать ее когда-нибудь, так почему бы не сразу?). Посмотрите еще раз на два последних предложения ответа. - person Quentin; 08.07.2018
comment
Все это знают! Дело не в ЭТОМ! Дело в том, что одним из преимуществ IIFE упоминается то, что они не загрязняют глобальную область видимости! Как вы, ребята, не видите разницы! Зачем они это делают, когда это происходит и при нормальной работе! - person Kumar Manish; 08.07.2018
comment
Единственное отличие состоит в том, что вместо того, чтобы писать function funcName() { what; } имя_функции(); вы пишете (функция () { что угодно; })(); что позволяет не оставлять funcName лежащим без дела. Это крошечная вещь, но в большом проекте с большим количеством одноразовых функций это может защитить вас от случайного повторного использования имени функции. - person Foo Bar; 10.12.2018