Expression de la fonction invoquée immédiatement (IIFE) vs pas

je vois beaucoup de code comme:

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

qui fait que la fonction anonyme s'exécute immédiatement. Mais quel est l'avantage de cela, par rapport au simple fait de mettre le code en ligne?

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

apparemment c'est en rapport avec la portée de la fonction, mais comme la fonction est anonyme et appelée par fenêtre, sa portée (i.e. this ) est globale, Non?

2
demandé sur Rob 2013-01-14 15:57:26

2 réponses

habituellement, vous auriez ceci:

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

la principale différence est que var1 n'encombre pas l'espace de noms global. Après cet appel, var1 est toujours le même qu'avant (généralement pas défini).

comme var1 ne peut être accédé à partir de la fonction défini dans la fermeture, il est dit"privé".

a part éviter les causes possibles de conflits, il est juste plus propre de ne pas garder les variables quand elles sont inutiles.

ici, vous n'avez pas de variable locale mais globale définie comme this.var1 . C'est probablement un bug, ou la raison se trouve ailleurs dans le code.

3
répondu Denys Séguret 2013-01-14 13:12:06

une raison: envelopper votre code dans une fonction anonyme vous permet de créer un module qui distingue une API publique de fonctions et variables privées qui ne sont utilisées qu'en interne dans le module. Cela évite de polluer l'espace-Nom global.

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

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

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

je pourrais dire:

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

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

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

mais alors le champ d'Application global inclut une fonction appelée helper qui n'est d'aucune utilité pour quiconque utilise votre module, et pourrait conduire à les conflits de nom avec d'autres modules.

je pourrais alternativement juste inclure helper comme une méthode de myApp.

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

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

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

cependant, je voudrais peut-être empêcher les utilisateurs d'appeler directement helper , auquel cas ce ne sera pas le cas.

3
répondu samfrances 2013-01-14 12:35:14