Quel est le but d'une fonction auto-exécutable en javascript?
en javascript, quand voudriez-vous utiliser ceci:
(function(){
//Bunch of code...
})();
pour ceci:
//Bunch of code...
16 réponses
tout est à propos de la portée variable. Les Variables déclarées dans la fonction d'auto-exécution sont, par défaut, disponibles uniquement pour le code dans la fonction d'auto-exécution. Cela permet d'écrire du code sans se soucier de la façon dont les variables sont nommées dans les autres blocs de code javascript.
par exemple:
(function(){
var foo = 3;
alert(foo);
})();
alert(foo);
cela va d'abord alerter" 3 " et ensuite lancer une erreur sur la prochaine alerte parce que foo n'est pas défini.
simpliste. De manière très normale, c'est presque rassurant:
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
cependant. Que se passe-t-il si j'ajoute une bibliothèque javascript vraiment pratique à ma page qui traduit des caractères avancés dans leurs représentations de niveau de base?
attendez... quoi?
je veux dire. Si quelqu'un tape un caractère, avec une sorte d'accent (comme les français ou en espagnol personnage) mais je veux seulement "l'anglais" personnages? A-z dans mon programme? Bien... Les Caractères espagnols 'n~' et français 'e/ '(j'ai utilisé deux caractères chacun pour ceux-ci, mais vous pouvez probablement faire le saut mental dans le caractère qui représente les accents), ces caractères peuvent être traduits en caractères de base de' n 'et'e'.
donc quelqu'un de bien a écrit un convertisseur de caractères complet là-bas que je peux inclure dans mon site... Je l'inclus.
Un problème: il a une fonction appelé "name" de même que ma fonction.
c'est ce qu'on appelle une collision. Nous avons deux fonctions déclarées dans le même champ d'application avec le même nom. Nous voulons éviter cela.
donc nous devons trouver un moyen de définir notre code.
la seule façon d'inclure le code dans javascript est de l'envelopper dans une fonction:
function main() {
// We are now in our own sound-proofed room and the
// character-converter libarary's name() function can exist at the
// same time as ours.
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
Qui pourrait résoudre notre problème. Tout est maintenant fermé et ne peut être accessible que depuis notre l'ouverture et la fermeture des accolades.
Nous avons une fonction dans une fonction... ce qui est bizarre à regarder, mais totalement légal.
un seul problème. Notre code ne fonctionne pas. Notre variable userName n'est jamais répercutée dans la console!
Nous pouvons résoudre ce problème en ajoutant un appel à notre fonction après notre bloc de code...
function main() {
// We are now in our own sound-proofed room and the
// character-converter libarary's name() function can exist at the
// same time as ours.
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
main();
ou avant!
main();
function main() {
// We are now in our own sound-proofed room and the
// character-converter libarary's name() function can exist at the
// same time as ours.
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
une préoccupation secondaire: Quelles sont les chances que le nom "main" n'ait pas encore été utilisé? ...donc, très, très mince.
nous avons besoin de plus de détermination de la portée. Et une façon d'exécuter automatiquement notre fonction main ().
nous arrivons maintenant aux fonctions d'auto-exécution (ou auto-exécution, auto-exécution, n'importe quoi).
((){})();
la syntaxe est aussi étrange que le péché. Cependant, il fonctionne.
lorsque vous envelopper une définition de fonction dans les parenthèses, et inclure une liste de paramètres (un autre ensemble ou des parenthèses!) il agit comme une fonction appel .
permet donc de regarder à nouveau notre code, avec une certaine syntaxe d'auto-exécution:
(function main() {
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
)();
ainsi, dans la plupart des tutoriels que vous lisez, vous allez maintenant être bombardé avec le terme "anonyme auto-exécution" ou quelque chose de similaire.
après de nombreuses années de développement professionnel, je fortement presser vous devez nommer chaque fonction que vous écrivez à des fins de débogage.
quand quelque chose va mal (et il va), vous serez en train de vérifier la rétrotrace dans votre navigateur. Il est toujours plus facile de restreindre vos problèmes de code quand les entrées dans la trace de pile ont des noms!
extrêmement long-winded et j'espère qu'il aide!
Auto-invocation (aussi connu comme auto-invocation) est quand une fonction exécute immédiatement son définition. C'est un modèle de base et sert de base pour de nombreux autres modèles de JavaScript développement.
je suis un grand fan :) de lui parce que:
- il maintient le code au minimum
- Il met en place la séparation de comportement de la présentation
- Il fournit un système de verrouillage qui empêche les conflits de noms
énormément – (Pourquoi dire son bien?)
- il s'agit de définir et d'exécuter une fonction à la fois.
- vous pourriez avoir cette fonction auto-exécution retourner une valeur et passer la fonction comme un paramètre à une autre fonction.
- c'est bon pour l'encapsulation.
- c'est aussi bon pour le bloc la portée.
- oui, vous pouvez enfermer tout votre .les fichiers js dans une fonction d'auto-exécution et peut prévenir la pollution globale de l'espace de noms. ;)
plus ici .
Namespacing. Les portées de JavaScript sont au niveau de la fonction.
Je ne peux pas croire qu'aucune des réponses ne mentionne les globals implicites.
la construction (function(){})()
ne protège pas contre les globals implicites, ce qui est pour moi la plus grande préoccupation, voir http://yuiblog.com/blog/2006/06/01/global-domination /
fondamentalement, le bloc de fonction s'assure que tous les "variateurs globaux" dépendants que vous avez définis sont confinés à votre programme, il ne vous protège pas contre la définition de globals implicites. JSHint ou autres, peuvent fournir des recommandations sur la façon de se défendre contre ce comportement.
la syntaxe plus concise var App = {}
offre un niveau de protection similaire et peut être enveloppée dans le bloc de fonctions lorsque les pages sont publiques. (voir de Braise.js ou SproutCore pour des exemples du monde réel de bibliothèques qui utilisent cette construction)
autant que private
propriétés vont, ils Douglas Crockford a de bonnes idées.
y a-t-il un paramètre et le" paquet de code " renvoie une fonction?
var a = function(x) { return function() { document.write(x); } }(something);
Fermeture . La valeur de something
est utilisée par la fonction assignée à a
. something
peut avoir une valeur variable (pour boucle) et chaque fois que a a une nouvelle fonction.
peut-être. Pour que les variables à l'intérieur de la déclaration de fonction ne polluent pas l'Espace-nom externe.
bien sûr, sur la moitié des implémentations JS là-bas, ils le feront de toute façon.
voici un bon exemple de l'utilité d'une fonction d'auto-invocation anonyme.
for( var i = 0; i < 10; i++ ) {
setTimeout(function(){
console.log(i)
})
}
sortie: 10, 10, 10, 10, 10...
for( var i = 0; i < 10; i++ ) {
(function(num){
setTimeout(function(){
console.log(num)
})
})(i)
}
sortie: 0, 1, 2, 3, 4...
Une différence, c'est que les variables déclarées dans la fonction sont locales, de sorte qu'ils disparaissent lorsque vous quittez la fonction et n'entrent pas en conflit avec d'autres variables dans un autre code.
j'ai lu toutes les réponses, quelque chose de très important manque ici , je vais embrasser. Il y a 2 raisons principales, pourquoi j'ai besoin de fonctions anonymes auto-exécutables, ou mieux dit " expression de fonction immédiatement invoquée (IIFE) " ":
- meilleure gestion de l'espace de noms (éviter la Pollution de L'espace de noms -> Module JS)
- fermetures (simulant des membres de classe privés, comme connu de OOP)
la première a été très bien expliquée. Pour le second, veuillez étudier l'exemple suivant:
var MyClosureObject = (function (){
var MyName = 'Michael Jackson RIP';
return {
getMyName: function () { return MyName;},
setMyName: function (name) { MyName = name}
}
}());
Attention 1: nous n'assignons pas une fonction à MyClosureObject
, plus le résultat de l'invocation de cette fonction . Être conscient de ()
à la dernière ligne.
Attention 2: Qu'avez-vous en plus pour connaître les fonctions dans Javascript est que les fonctions internes obtiennent l'accès aux paramètres et aux variables des fonctions, ils sont définis à l'intérieur.
essayons quelques expériences:
je peux obtenir MyName
à l'aide getMyName
et ça marche:
console.log(MyClosureObject.getMyName());
// Michael Jackson RIP
candide approche pourrait ne pas fonctionner:
console.log(MyClosureObject.MyName);
// undefined
mais je peux définir un autre nom et obtenez le résultat attendu:
MyClosureObject.setMyName('George Michael RIP');
console.log(MyClosureObject.getMyName());
// George Michael RIP
Edit: dans l'exemple ci-dessus MyClosureObject
est conçu pour être utilisé sans le préfixe new
, donc par convention il ne doit pas être capitalisé.
fonction auto-invoquée en javascript:
une expression auto-invocatrice est invoquée (démarrée) automatiquement, sans être appelée. Une expression auto-invocatrice est invoquée juste après sa création. Ceci est essentiellement utilisé pour éviter les conflits de noms ainsi que pour réaliser l'encapsulation. Les variables ou les objets déclarés ne sont pas accessibles en dehors de cette fonction. Pour éviter les problèmes de minimisation(filename.min) toujours utiliser l'auto exécutée fonction.
puisque les fonctions en Javascript sont un objet de première classe, en le définissant de cette façon, il définit effectivement une" classe " un peu comme C++ ou C#.
cette fonction peut définir des variables locales, et avoir des fonctions à l'intérieur. Les fonctions internes (méthodes d'instance) auront accès aux variables locales (variables d'instance), mais ils seront isolés du reste du script.
(function(){
var foo = {
name: 'bob'
};
console.log(foo.name); // bob
})();
console.log(foo.name); // Reference error
en fait, la fonction ci-dessus sera traitée comme une expression de fonction sans nom.
le but principal d'envelopper une fonction avec des parenthèses fermées et ouvertes est d'éviter de polluer l'espace global.
les variables et les fonctions à l'intérieur de l'expression de fonction sont devenues privées (I. e) ils ne seront pas disponibles en dehors de la fonction.
fonction d'auto-exécution sont utilisés pour gérer la portée d'une Variable.
La portée d'une variable est la région de votre programme dans lequel il est défini.
une variable globale a une portée globale; elle est définie partout dans votre code JavaScript et peut être consultée de n'importe où dans le script, même dans vos fonctions. D'autre part, les variables déclarées dans une fonction ne sont définies que dans le corps de la fonction. Ils sont locaux les variables ont une portée locale et ne peuvent être consultées qu'à l'intérieur de cette fonction. Les paramètres de fonction comptent aussi comme variables locales et sont définis seulement dans le corps de la fonction.
comme montré ci-dessous, vous pouvez accéder à la variable globalvariable à l'intérieur de votre fonction et aussi noter que dans le corps d'une fonction, une variable locale a priorité sur une variable globale avec le même nom.
var globalvar = "globalvar"; // this var can be accessed anywhere within the script
function scope() {
alert(globalvar);
localvar = "localvar" //can only be accessed within the function scope
}
scope();
donc essentiellement une fonction auto-exécutante permet d'écrire du code sans se soucier de la façon dont les variables sont nommées dans les autres blocs de code javascript.
il semble que cette question a été répondu tout prêt, mais je vais poster mes commentaires de toute façon.
je sais quand j'aime utiliser des fonctions auto-exécutables.
var myObject = {
childObject: new function(){
// bunch of code
},
objVar1: <value>,
objVar2: <value>
}
la fonction me permet d'utiliser du code supplémentaire pour définir les attributs et les propriétés de childObjects pour du code plus propre, comme la mise en place de variables couramment utilisées ou l'exécution d'équations mathématiques; Oh! ou vérification des erreurs. au lieu d'être limité à l'instanciation d'objet imbriqué la syntaxe de...
object: {
childObject: {
childObject: {<value>, <value>, <value>}
},
objVar1: <value>,
objVar2: <value>
}
Codage en général a beaucoup d'obscurs façons de faire les mêmes choses, de vous faire demander, "Pourquoi s'embêter?"Mais de nouvelles situations continuent de surgir où l'on ne peut plus compter uniquement sur les principes de base.
IIRC il permet de créer des propriétés privées et des méthodes.