Quel est le but de l'habillage de l'ensemble des fichiers Javascript dans les fonctions anonymes comme “(fonction(){ ... })()”?
J'ai lu beaucoup de Javascript, dernièrement, et j'ai remarqué que le fichier entier est enveloppé comme suit dans le .js fichiers à importer.
(function() {
...
code
...
})();
Quelle est la raison pour faire cela plutôt que d'un simple ensemble de fonctions constructeur?
- Depuis j'imagine que ce sera utilisé par beaucoup de gens, s'il vous plaît n'oubliez pas de clôture ;
- Cette technique est appelée "IIFE" je pense. Cela signifie Immédiatement appelé Expression de Fonction en.wikipedia.org/wiki/Immediately-invoked_function_expression
- double possible de Quel est le but d'une auto de l'exécution de la fonction en javascript?
Vous devez vous connecter pour publier un commentaire.
C'est généralement pour l'espace de noms (voir plus loin) et le contrôle de la visibilité des fonctions de membre et/ou des variables. Pensez-y comme à une définition de l'objet. jQuery plugins sont généralement écrites comme ceci.
En Javascript, vous pouvez imbriquer des fonctions. Donc, ce qui suit est juridique:
Maintenant, vous pouvez appeler
outerFunction()
, mais le visiblity deinnerFunction()
est limitée à la portée deouterFunction()
, c'est à dire privé deouterFunction()
. Essentiellement, il suit le même principe que les variables en Javascript:En conséquence:
Dans le scénario ci-dessus, vous pouvez appeler
globalFunction()
à partir de n'importe où, mais vous ne pouvez pas appelerlocalFunction1
oulocalFunction2
.Ce que vous faites lorsque vous écrivez
(function() { ... code ... })()
, c'est que vous êtes du code à l'intérieur d'une fonction littérale (le sens de l'ensemble de "l'objet" est en fait une fonction). Après cela, vous êtes auto-invocation de la fonction (la dernière()
). Donc, l'avantage majeur de cette comme je l'ai mentionné avant, est que vous pouvez avoir privé des méthodes/fonctions et propriétés:Dans le premier exemple, globalFunction() est la fonction publique qui pourrait être appelé à l'accès du public de la fonctionnalité, mais dans l'exemple ci-dessus comment l'appelez-vous? Ici, l'auto-invocation de la fonction rend le code d'exécuter automatiquement au démarrage. Comme vous pouvez l'ajouter initMyStuff(); au-dessus de tout .fichier js et il sera automatiquement exécuté dans le cadre de la portée globale, cette auto-invocation de la fonction sera également exécuter automatiquement, mais puisque c'est une fonction sans nom, il ne peut pas être appelée plusieurs fois comme initMyStuff() pourrait être.
La chose intéressante est que vous pouvez également définir les choses à l'intérieur et à l'exposer au monde extérieur (un exemple de namespacing de sorte que vous pouvez créer votre propre bibliothèque/plugin):
Maintenant, vous pouvez appeler
myPlugin.public_function1()
, mais vous ne pouvez pas accéderprivate_function()
! Donc, assez semblable à une définition de classe. Pour mieux comprendre ce processus, je vous recommande les liens suivants pour certains pour en savoir plus:MODIFIER
J'ai oublié de mentionner. Dans cette finale
()
, vous pouvez passer tout ce que vous voulez à l'intérieur. Par exemple, lorsque vous créez des plugins jQuery, vous passez dansjQuery
ou$
comme suit:Donc ce que vous faites ici est de définir une fonction qui prend un paramètre (appelé
jQ
, une variable locale, et connu seulement à cette fonction). Alors vous êtes auto-invocation de la fonction et en lui passant un paramètre (appelé aussijQuery
, mais ce on est du monde extérieur et une référence à la réalité de jQuery). Il n'y a aucune urgence à le faire, mais il ya certains avantages:Plus tôt, j'ai décrit comment ces fonctions de s'exécuter automatiquement au démarrage, mais si ils s'exécutent automatiquement, qui est en passant les arguments? Cette technique suppose que tous les paramètres sont définis comme des variables globales. Donc, si jQuery n'était pas défini comme une variable globale cet exemple ne fonctionne pas, et ne pouvait pas être appelé de toute autre façon depuis notre exemple est une fonction anonyme. Comme vous pouvez le deviner, l'une des choses jquery.js ne pendant l'initialisation est de définir un 'jQuery' variable globale, ainsi que celle de ses plus célèbres '$' variable globale, ce qui permet à ce code fonctionne après jquery.js est inclus.
;(function(jQ) { ... code ... })(jQuery);
de Cette façon, si quelqu'un a laissé un point-virgule dans leur script, il ne serait pas briser la vôtre, surtout si vous envisagez de rapetisser et de les enchaîner votre script avec les autres.(function (context) { ..... })(this)
qui vous permet ensuite de fixer quoi que ce soit vous aimez le contexte parent donc de l'exposer.this.myLib = myLib
,define(myLib)
,module.exports = myLib
ou une combinaison de ceux-ci.En bref
Résumé
Dans sa forme la plus simple, cette technique vise à envelopper le code à l'intérieur d'un portée de la fonction.
Il aide diminue les chances de:
Il ne pas détecter lorsque le document est prêt, il n'est pas une sorte de
document.onload
niwindow.onload
Il est communément connu comme un
Immediately Invoked Function Expression (IIFE)
ouSelf Executing Anonymous Function
.Code Expliqué
Dans l'exemple ci-dessus, toute variable définie dans la fonction (c'est à dire déclarées à l'aide de
var
) sera "privé" et accessible à l'intérieur de la portée de la fonction SEULE (Vivin Paliath met). En d'autres termes, ces variables ne sont pas visibles/accessibles en dehors de la fonction. Voir la démo en direct.Javascript a la fonction de cadrage. "Les paramètres et les variables définies dans une fonction ne sont pas visibles à l'extérieur de la fonction, et qu'une variable définie n'importe où à l'intérieur d'une fonction est visible partout dans la fonction." (à partir de "Javascript: Les Bonnes Parties").
Plus de détails
Code Alternatif
En fin de compte, le code posté avant peut également être fait comme suit:
Voir la démo en direct.
Les Racines
Itération 1
Un jour, quelqu'un a probablement pensé "il doit y avoir un moyen d'éviter de nommer 'myMainFunction", puisque tout ce que nous voulons c'est de l'exécuter immédiatement."
Si vous aller à l'essentiel, vous découvrez que:
expression
: quelque chose de l'évaluation de la valeur. c'est à dire3+11/x
statement
: ligne(s) de code à faire quelque chose, MAIS il ne pas évaluer la valeur. c'est à direif(){}
De même, les expressions de fonction d'évaluer la valeur. Et l'une des conséquences (je suppose?) c'est qu'ils peuvent être immédiatement appelé:
Donc notre exemple plus complexe devient:
Voir la démo en direct.
Itération 2
La prochaine étape est la pensée "pourquoi avez -
var myMainFunction =
si on ne peut même pas l'utiliser!?".La réponse est simple: essayez de supprimer, comme ci-dessous:
Voir la démo en direct.
Il ne fonctionnera pas parce que "les déclarations de fonction ne sont pas invokable".
Le truc, c'est qu'en supprimant
var myMainFunction =
nous avons transformé le expression de fonction dans un déclaration de fonction. Voir les liens dans "Ressources" pour plus de détails sur cette.La prochaine question est "pourquoi je ne peux pas le garder comme une expression de fonction avec autre chose que
var myMainFunction =
?La réponse est "vous pouvez", et il ya effectivement beaucoup de façons que vous pourriez faire ceci: l'ajout d'un
+
, un!
, un-
, ou peut-être enveloppant dans une paire de parenthèses (comme c'est maintenant fait par convention), et de plus je crois. À titre d'exemple:ou
ou
Donc, une fois que la modification est ajoutée à ce qui a été une fois notre "Code Alternatif", nous avons retour à exactement le même code que celui utilisé dans le "Code Expliqué" exemple
Lire plus sur
Expressions vs Statements
:Démystifier Les Étendues
Une chose que l'on peut se demander est "ce qui arrive quand vous ne définissez PAS la variable "correctement" à l'intérieur de la fonction -- c'est à dire de faire une simple affectation à la place?"
Voir la démo en direct.
En gros, si une variable n'a pas été déclarée dans son champ d'application actuel est affectée une valeur, puis "d'un regard l'étendue de la chaîne se produit jusqu'à ce qu'il trouve la variable ou de la frappe de la portée mondiale (qui sera le créer)".
Quand, dans un environnement de navigateur (vs un environnement de serveur comme nodejs) la portée globale est définie par la
window
objet. Par conséquent, nous pouvons fairewindow.myOtherFunction()
.Mes "Bonnes pratiques" astuce à ce sujet est à toujours utiliser
var
lors de la définition de quelque chose: si c'est un nombre, objet ou la fonction, & même quand, dans la portée globale. Cela rend le code beaucoup plus simple.Remarque:
block scope
(mise à Jour: le bloc de portée des variables locales ajouté dans ES6.)function scope
&global scope
(window
champ d'application dans un environnement de navigateur)Lire plus sur
Javascript Scopes
:Ressources
Prochaines Étapes
Une fois que vous obtenez cette
IIFE
concept, il conduit à lamodule pattern
, ce qui est généralement fait en tirant parti de cette IIFE modèle. Amusez-vous 🙂Javascript dans un navigateur ne prend véritablement un couple de efficace étendues: la fonction de l'étendue et de la portée globale.
Si une variable n'est pas dans la portée de la fonction, c'est dans la portée globale. Et les variables globales sont généralement mauvais, c'est donc une construction de garder une bibliothèque de variables à lui-même.
Que l'on appelle une fermeture. Essentiellement, il scelle le code à l'intérieur de la fonction, de sorte que d'autres bibliothèques ne pas interférer avec elle. Il est similaire à la création d'un espace de noms dans les langages compilés.
Exemple. Supposons que j'écris:
Maintenant d'autres bibliothèques ne peuvent pas accéder à la variable
x
j'ai créé pour une utilisation dans ma bibliothèque.(function(){ ... return { publicProp1: 'blah' }; })();
. Évidemment pas parfaitement parallèle à namespacing, mais il peut aider à penser de cette façon.Vous pouvez utiliser la fonction de fermetures comme données dans de plus grandes expressions, comme dans cette méthode de détermination de la prise en charge du navigateur pour certains de l'html5 objets.
En plus de garder les variables locales, un très pratique d'utilisation est lors de l'écriture d'une bibliothèque à l'aide d'une variable globale, vous pouvez donner un plus court nom de la variable à utiliser dans la bibliothèque. Il est souvent utilisé dans l'écriture de plugins jQuery, depuis jQuery vous permet de désactiver la variable $ pointant vers jQuery, à l'aide de jQuery.noConflict(). Dans le cas où il est désactivé, votre code peut toujours utiliser $ et de ne pas se briser si vous venez de le faire:
Nous devons également utiliser 'use strict' dans le champ d'application de la fonction pour vous assurer que le code doit être exécuté en "mode strict". Exemple de code ci-dessous