391 votes

Pourquoi avez-vous besoin d'appeler une fonction anonyme sur la même ligne?

Je suis en train de lire quelques posts au sujet de fermetures et de voir ce truc dans tous les endroits, mais il n'y a pas d'explication comment cela fonctionne - juste à chaque fois je me dit à l'utiliser...:

// Create a new anonymous function, to use as a wrapper
(function(){
    // The variable that would, normally, be global
    var msg = "Thanks for visiting!";

    // Binding a new function to a global object
    window.onunload = function(){
        // Which uses the 'hidden' variable
        alert( msg );
    };
// Close off the anonymous function and execute it
})();

Ok, je vois que nous allons créer de nouvelles fonction anonyme, et puis l'exécuter. Alors, après que ce simple code devrait fonctionner (et il le fait):

(function (msg){alert(msg)})('SO');

Ma question est: quel genre de magie viennent lieu ici? Je pensais que lorsque j'ai écrit:

(function (msg){alert(msg)})

puis nouvelle fonction sans nom sera créé comme la fonction ""(msg) ...

mais alors pourquoi cela ne fonctionne pas?

(function (msg){alert(msg)});
('SO');

Pourquoi il faut être dans la même ligne?

Pourrait s'il vous plaît m'indiquer le post ou me donner l'explication?

384voto

SolutionYogi Points 16697

De chute le point-virgule après la définition de la fonction.

(function (msg){alert(msg)})
('SO');

Ci-dessus devrait fonctionner.

Page de DÉMONSTRATION: http://jsbin.com/ujazi

Code: http://jsbin.com/ujazi/edit

J'ai discuté de ce genre de modèle dans ce post:

jQuery et $ questions

EDIT:

Si vous regardez l'ECMA script spécification, il y a 3 façons de définir une fonction. (Page 98), De L'Article 13 De Définition De Fonction)

1. À l'aide de la Fonction constructeur

var sum = new Function('a','b', 'return a + b;');
alert(sum(10, 20)); //alerts 30

2. À l'aide de déclaration de Fonction.

function sum(a, b)
{
    return a + b;
}

alert(sum(10, 10)); //Alerts 20;

3. Expression De Fonction

var sum = function(a, b) { return a + b; }

alert(sum(5, 5)); // alerts 10

Ainsi, vous pouvez demander, quelle est la différence entre déclaration et d'expression?

Par l'ECMA Script spécifications:

FunctionDeclaration : Identificateur de fonction ( FormalParameterListopt ){ FunctionBody }

FunctionExpression : fonction Identifieropt ( FormalParameterListopt ){ FunctionBody }

Si vous remarquez, 'identifiant' est en option pour la fonction d'expression. Et quand vous n'avez pas d'identifiant, vous devez créer une fonction anonyme. Cela ne signifie pas que vous ne pouvez pas spécifier un identificateur.

Cela signifie suivante est valide.

var sum = function mySum(a, b) { return a + b; }

Point Important à noter est que vous pouvez utiliser 'mySum' seulement à l'intérieur de la mySum corps de la fonction, et non à l'extérieur. Voir l'exemple suivant:

var test1 = function test2() { alert(typeof test2); }

alert(typeof(test2)); //alerts 'undefined', surprise! 

test1(); //alerts 'function' because test2 is a function.

Démonstration En Direct

Comparez cela à

 function test1() { alert(typeof test1) };

 alert(typeof test1); //alerts 'function'

 test1(); //alerts 'function'

Armés de cette connaissance, nous allons essayer d'analyser votre code.

Lorsque vous avez un code comme,

    function(msg) { alert(msg); }

Vous avez créé une expression de fonction. Et vous pouvez exécuter cette fonction d'expression en l'enveloppant à l'intérieur de la parenthèse.

    (function(msg) { alert(msg); })('SO'); //alerts SO.

133voto

seth Points 18409

Il est appelé auto-fonction invoquée.

Ce que vous faites lorsque vous appelez (function(){}) est de retour d'une fonction d'objet. Lorsque vous ajoutez () , elle est invoquée et n'importe quoi dans le corps est exécuté. L' ; "indique la fin de l'énoncé, c'est pourquoi le 2e invocation échoue.

Il y a un bon article sur le modèle ici. Je suis sûr qu'il y en existe d'autres.

94voto

Benxamin Points 1491

Une chose que je trouve étrange, c'est que les "()" sont des opérateurs de regroupement.

Voici votre base en fonction déclarée.

Ex. 1:

var message = 'SO';

function foo(msg) {
    alert(msg);
}

foo(message);

Les fonctions sont des objets, et peuvent être regroupées. Donc, nous allons jeter les parenthèses autour de la fonction.

Ex. 2:

var message = 'SO';

function foo(msg) {  //declares foo
    alert(msg);
}

(foo)(message);     // calls foo

Maintenant, au lieu de déclarer et à tout de suite appeler la même fonction, on peut utiliser de base de la substitution de la déclarer comme nous l'appelons.

Ex. 3.

var message = 'SO';

(function foo(msg) {
    alert(msg);
})(message);          // declares & calls foo

Enfin, nous n'avons pas besoin de ce supplément de foo parce que nous n'utilisons pas le nom pour l'appeler! Les fonctions peuvent être anonymes.

Ex. 4.

var message = 'SO';

(function (msg) {   // remove unnecessary reference to foo
    alert(msg);
})(message);

Pour répondre à votre question, veuillez vous référer à l'Exemple 2. Votre première ligne déclare quelques pas de nom de la fonction et des groupes, mais ne pas l'appeler. Le deuxième ligne des groupes d'une chaîne de caractères. Les deux ne rien faire. (Vincent du premier exemple.)

(function (msg){alert(msg)});  
('SO');                       // nothing.

(foo); 
(msg); //Still nothing.

Mais

(foo)
(msg); //works

24voto

Vincent Robert Points 16530

Une fonction anonyme n'est pas une fonction avec le nom "". C'est simplement une fonction sans nom.

Comme toute autre valeur en Javascript, une fonction n'a pas besoin d'un nom pour être créé. Mais il est beaucoup plus utile de se lier à un nom, tout comme toute autre valeur.

Mais comme n'importe quelle autre valeur, vous avez parfois envie de l'utiliser sans la lier à un nom, c'est l'auto-invoquer de motif.

Voici une fonction et un certain nombre, qui n'est pas lié, ils ne font rien et ne peut jamais être utilisé:

function(){ alert("plop"); }
2;

Nous avons donc de les stocker dans une variable pour pouvoir l'utiliser comme n'importe quelle autre valeur:

var f = function(){ alert("plop"); }
var n = 2;

Vous pouvez également utiliser un syntatic sucre de lier la fonction à une variable:

function f(){ alert("plop"); }
var n = 2;

Mais si le fait de les nommer n'est pas nécessaire et de créer plus de confusion et de moins de lisibilité, vous pouvez simplement utiliser tout de suite.

(function(){ alert("plop"); })(); // will display "plop"
alert(2 + 3); // will display 5

Ici, ma fonction et mes chiffres ne sont pas liés à une variable, mais peut encore être utilisé.

Dit comme ça, ça ressemble à de l'auto-invocation de la fonction ont pas de valeur réelle. Mais vous devez garder à l'esprit que Javascript portée délimiteur est la fonction et non pas le bloc ({}).

Ainsi, un auto-invocation de fonction a le même sens que C++, C# ou Java bloc. Ce qui signifie que la variable créée à l'intérieur ne sera pas "fuite" en dehors de la portée. Ceci est très utile en Javascript afin de ne pas polluer la portée globale.

19voto

jrockway Points 23734

C'est juste du fonctionnement de Javascript. Vous pouvez déclarer une fonction nommée:

function foo(msg){
   alert(msg);
}

Et de l'appeler:

foo("Hi!");

Ou, vous pouvez déclarer une fonction anonyme:

var foo = function (msg) {
    alert(msg);
}

Et l'appeler:

foo("Hi!");

Ou, vous pouvez juste ne jamais lier la fonction d'un nom:

(function(msg){
   alert(msg);
 })("Hi!");

Les fonctions peuvent également retourner des fonctions:

function make_foo() {
    return function(msg){ alert(msg) };
}

(make_foo())("Hi!");

Elle ne vaut rien que les variables définies avec "var" dans le corps de l' make_foo sera fermé par chaque fonction renvoyée par make_foo. C'est une clôture, et cela signifie que toute modification apportée à la valeur d'une fonction sera visible par un autre.

Cela vous permet d'encapsuler l'information, si vous le désirez:

function make_greeter(msg){
    return function() { alert(msg) };
}

var hello = make_greeter("Hello!");

hello();

C'est juste la façon dont presque chaque langage de programmation, mais Java fonctionne.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X