2009-08-19 2 views
3

Quelqu'un peut-il expliquer pourquoi cela fonctionne:La fonction JavaScript simple avec invocation immédiate ne fonctionne pas ... pourquoi?

var sayHello = function (name) { 
    alert("Hello there " + name + "!"); 
}("Mike"); 

Bien que cela ne fait pas:

function sayHello (name) { 
    alert("Hello there " + name + "!"); 
}("Mike"); 

Mike Peat

+0

Merci les gars - Je ne cherche pas vraiment à faire fonctionner cela, mais plutôt j'écris un cours JavaScript dans lequel j'essaie de donner aux étudiants une bonne compréhension de ce qui se passe réellement . Si je comprends bien (! Peut-être imparfaite) est que: fonction foo() {} était juste un raccourci pour: var foo = function() {} et qui étaient * vraiment * anonyme toutes les fonctions JavaScript, mais nous avons eu des références à eux, c'est pourquoi le fait qu'une forme a fonctionné mais l'autre ne m'a pas perplexe. Ce que je voulais vraiment, c'était le plus radical: function() {}(); –

Répondre

0

Edité parce que ma réponse avait mal lu le message original:

Comme votre fonction n'est plus assignée comme une fonction lambda à une valeur, invoquer la fonction après ("Mike") ne fonctionnera pas s il n'y a pas de valeur pour invoquer l'appel. Comme d'autres ont suggéré enroulant cela avec des parenthèses pour créer une variable temporaire sera toujours vous invoquons la fonction anonyme:

(function sayHello (name) { 
    alert("Hello there " + name + "!"); 
})('Mike'); 
+0

Mais je pense qu'il essaie aussi de créer une fonction auto-invoquant. – Brian

+0

Ah oui, c'est correct..qui ne fonctionnera pas dans ce contexte car il n'est jamais assigné à une valeur à invoquer ensuite. Ma faute. Éditera. –

4

Votre second code est en fait:

function sayHello (name) { 
    alert("Hello there " + name + "!"); 
} 

("Mike"); 

Donc, vous première fonction déclarez « sayHello » , puis vous exécutez la "déclaration":

("Mike"); 

qui ne fait rien.

+0

Cela ne répond pas ce qu'il veut réellement faire cependant, qui appelle la fonction anonyme. Voir la réponse de Brian. –

+1

Il explique pourquoi cela ne fonctionne pas, ce qui est EXACTEMENT ce que l'OP a demandé. –

+0

Philippe - c'est correct je pense, mais ce que je ne voyais pas, c'est que dans la première forme, l'affectation du lambda à la var * devrait * être en fait terminée par un point virgule (un fait déguisé par les accolades de la fonction body), qui manque est ce qui permet au ("Mike") d'invoquer la fonction. Est-ce vrai, pensez-vous? –

3

Cela fonctionne:

(function sayHello (name) { 
     alert("Hello there " + name + "!"); 
    })("Mike"); 

Notez la parens enveloppant la fonction elle-même. Vous pouvez également supprimer le nom de la fonction "sayHello" et cela fonctionnera toujours. En ce qui concerne pourquoi? Je ne suis pas positif. Peut-être qu'en l'assignant à une variable et en n'utilisant pas les wrapping(), vous l'attribuez en fait à sayHello puis en exécutant say hello, pas la fonction anonyme.

0

Autour de la définition de la fonction dans () avant de l'appeler fonctionne:

(function sayHello(name) { 
    alert("Hello there " + name + "!"); 
})("Mike"); 

// however -- 
alert(typeof sayHello); // undefined 

Donc, si vous voulez faire quelque chose comme ça - vous pourriez tout aussi bien en faire une fonction anonyme:

(function(name) { 
    alert("Hello there " + name + "!"); 
})("Mike"); 

Et je ne suis pas sûr que ce soit nécessaire - mais pour la sécurité - chaque fois que j'utilise une fermeture comme celle-ci, je l'entoure toujours ()

1
var sayHello = function (name) { 
    alert("Hello there " + name + "!"); 
}("Mike"); 

Ceci crée une fonction anonyme et l'appelle tout de suite avec le paramètre "Mike". Ensuite, la valeur de retour de cet appel de fonction est affectée à la variable sayHello.

function sayHello (name) { 
    alert("Hello there " + name + "!"); 
}("Mike"); 

Cette juste définit une fonction normale avec le nom sayHello et la déclaration de la fonction se termine après la fermeture}. Puis suit l'instruction ("Mike") qui est valide, mais ne fait rien.

+0

Il n'y a pas de fonction 'normale'. 'function sayHello() {}' est seulement un raccourci pour 'var sayHello = function() {}'. Voir JavaScript de JavaScript de Crockford: The Good Parts * pour d'autres références. –

+0

Ah! Mais cela m'aide à comprendre! La fonction foo()() peut être/shorthand pour var foo = function() {}, mais la première est l'instruction function, tandis que la dernière est l'affectation du résultat d'une instruction à une variable. Je pense que je pourrais être plus clair à ce sujet! ;-) (Mais je ne suis pas/tout à fait/là encore!) –

13

Tout ce que vous devez comprendre ici est la différence entre FunctionExpression s et FunctionDeclaration s en Javascript.

Lorsque vous entourez fonction entre parenthèses -

(function sayHello (name) { 
    alert("Hello there " + name + "!"); 
})("Mike"); 

- vous, techniquement, appliquer un opérateur de regroupement lui. Une fois appliquée, la production globale n'est plus une FunctionDeclarataion, mais une FunctionExpression. Comparer -

function foo(){ } // FunctionDeclaration 

(function foo(){ }); // FunctionExpresson 
typeof function(){ }; // FunctionExpression 
new function(){ }; // FunctionExpression 

FunctionExpression (contrairement à FunctionDeclaration), comme tout autre MemberExpresson peut être jointe à Arguments ("(" et ")") et se traduira par l'invocation de la fonction. C'est exactement pourquoi la fonction est appelée dans votre premier exemple et non dans une seconde.

Notez que FunctionExpression s sont autorisés à avoir en option Identifiant s (contrairement à FunctionDeclaration s qui doit toujours avoir un), de sorte que vous pouvez facilement omettre « sayHello » et se retrouver avec soi-disant fonction anonyme expression -

(function(){ 
    alert('...'); 
}); 

Vous pouvez consulter my article on named function expressions, qui plonge dans les détails subtils de différence entre les expressions de fonction et les déclarations de fonctions dans beaucoup plus de détails.

+0

Merci kangax - lire votre article maintenant! ;-) –

+0

Il semble que votre lien d'article est cassé. (Par conséquent) Quelques ressources supplémentaires: http: //kangax.github.com/nfe /, http://stackoverflow.com/questions/1013385/what-is-the-difference-between-a-function-expression-vs-declaration-in-javascrip, http://stackoverflow.com/questions/939386/javascript-immediate-function-invocation-syntax, http://my.safaribooksonline.com/book/programming/javascript/9781449399115/functions/immediate_functions – SunnyRed

+0

Merci, mis à jour ce lien. – kangax

Questions connexes