Выражение с немедленной вызывной функцией (IIFE) против не

Я вижу много кода вроде:

var myApp ={};
(function() {
    console.log("Hello");
    this.var1 = "mark";     //"this" is global, because it runs immediately on load.  Caller is global
    myApp.sayGoodbye = function() {
        console.log("Goodbye");
    };
})();

Это приводит к немедленному выполнению анонимной функции. Но в чем преимущество этого, по сравнению с просто введением кода в строку?

var myApp ={};
console.log("Hello");
var1 = "mark";     
myApp.sayGoodbye = function() {
    console.log("Goodbye");
};

По-видимому, это связано с областью действия функции, но поскольку функция анонимна и вызывается окном, ее область (т.е. this) является глобальной, no?

Ответ 1

Обычно у вас есть следующее:

        var myApp ={};
        (function() {
            console.log("Hello");
            var var1 = "mark";  
            myApp.sayGoodbye = function() {
                console.log("Goodbye");
            };
        })();

Основное отличие состоит в том, что var1 не загромождает глобальное пространство имен. После этого вызова var1 по-прежнему остается прежним (обычно undefined).

Как var1 можно получить доступ только от функций, определенных в закрытии, сказано "private".

Кроме того, избегая возможных причин конфликтов, он просто не должен содержать глобальные переменные, когда они бесполезны.

Здесь у вас нет локальной переменной, а глобальная - this.var1. Вероятно, это ошибка, или причина будет найдена в другом месте кода.

Ответ 2

Одна из причин: объединение вашего кода в анонимную функцию позволяет создать модуль, который отличает открытый API от частных функций и переменных, которые используются только внутри модуля. Это позволяет избежать загрязнения глобального пространства имен.

var myApp ={};
(function() {
    console.log("Hello");
    this.var1 = "mark";

    function helper() {/*Some code here*/;}

    myApp.sayGoodbye = function() {
        helper()
        console.log("Goodbye");
    };
})();

Я мог бы сказать:

var myApp ={};
console.log("Hello");
var var1 = "mark";

function helper() {/*Some code here*/;}

myApp.sayGoodbye = function() {
    helper()
    console.log("Goodbye");
};

Но тогда глобальная область действия включает в себя функцию под названием helper, которая бесполезна для любого, кто использует ваш модуль, и может привести к возможным конфликтам именования с другими модулями.

Я мог бы просто включить helper как метод myApp.

var myApp ={};
console.log("Hello");
var var1 = "mark";

myApp.helper = function() {/*Some code here*/;}

myApp.sayGoodbye = function() {
    this.helper()
    console.log("Goodbye");
};

Однако я могу запретить пользователям напрямую звонить helper, и в этом случае это не будет сделано.