Comment fonctionne cette syntaxe JavaScript/JQuery: (function (window, undefined) {}) (window)?

avez-vous déjà regardé sous le capot le code source jQuery 1.4 et remarqué comment il est encapsulé de la façon suivante:

(function( window, undefined ) {

  //All the JQuery code here 
  ...

})(window);

j'ai lu un article sur L'espace de nom JavaScript et un autre appelé une paire importante de Parens ," donc je sais ce qui se passe ici.

Mais je n'ai jamais vu cette syntaxe particulière avant. Qu'est-ce que que undefined fait là? Et pourquoi window doit-il être passé et apparaître à nouveau à la fin?

150
demandé sur dkinzer 2010-04-26 22:58:59

5 réponses

la variable non définie est une variable normale et peut être changée simplement avec undefined = "new value"; . Donc jQuery crée une variable locale "non définie" qui est vraiment non définie.

la variable window est rendue locale pour des raisons de performance. Parce que quand JavaScript regarde une variable, il passe d'abord par les variables locales jusqu'à ce qu'il trouve le nom de la variable. Quand il n'est pas trouvé, JavaScript passe par la portée suivante, etc. jusqu'à ce qu'il passe à travers les variables globales. Donc, si l' la variable window est rendue locale, JavaScript peut la chercher plus rapidement. Pour plus d'informations: Accélérez votre JavaScript - Nicholas C. Zakas

156
répondu Vincent 2014-02-07 23:49:10

Non défini

en déclarant undefined comme argument mais en ne lui passant jamais de valeur, garantit qu'il est toujours non défini, car il s'agit simplement d'une variable dans le champ d'Application global qui peut être écrasée. Cela fait de a === undefined une alternative sûre à typeof a == 'undefined' , ce qui sauve quelques caractères. Il rend également le code plus convivial, car undefined peut être raccourci à u par exemple, en sauvegardant quelques caractères supplémentaires.

fenêtre

passer window comme argument garde une copie dans la portée locale, qui affecte la performance: http://jsperf.com/short-scope . Tous les accès à window devront désormais parcourir un niveau de moins dans la chaîne scope. Comme pour undefined , une copie locale permet une minification plus agressive.


Note complémentaire:

bien que cela n'ait peut-être pas été l'intention des développeurs de jQuery, passer dans window permet à la bibliothèque d'être plus facilement intégrée dans des environnements Javascript côté serveur, par exemple noeud.js - où il n'y a pas d'objet global window . Dans une telle situation, une seule ligne doit être changée pour remplacer l'objet window par un autre. Dans le cas de jQuery, un objet simulé window peut être créé et passé dans le but de racler HTML (une bibliothèque telle que jsdom peut le faire).

52
répondu David Tang 2011-02-09 14:08:14

D'autres ont expliqué undefined . undefined est comme une variable globale qui peut être redéfinie à n'importe quelle valeur. Cette technique est d'empêcher toutes les vérifications non définies de briser si quelqu'un a écrit dire, undefined = 10 quelque part. Un argument qui n'est jamais passé est garanti pour être vrai undefined , indépendamment de la valeur de la variable undefined .

la raison de passer la fenêtre peut être illustrée par l'exemple suivant.

(function() {
   console.log(window);
   ...
   ...
   ...
   var window = 10;
})();

Qu'est-ce que le log de la console? La valeur de l'objet window droit? Faux! 10? Faux! Il enregistre undefined . L'interpréteur Javascript (ou compilateur JIT) le réécrit de cette façon -

(function() {
   var window; //and every other var in this function

   console.log(window);
   ...
   ...
   ...
   window = 10;

})();

cependant, si vous obtenez la variable window comme argument, il n'y a pas de var et donc pas de surprises.

Je ne sais pas si jQuery le fait, mais si vous redéfinissez window variable locale n'importe où dans votre fonction quelle qu'en soit la raison, c'est une bonne idée de l'emprunter à global scope.

15
répondu Chetan Sastry 2010-04-26 19:36:18

window est passé comme ça juste au cas où quelqu'un décide de redéfinir l'objet window dans IE, je suppose la même chose pour undefined , au cas où il est ré-assigné d'une manière ou d'une autre plus tard.

haut window dans le script est juste de nommer l'argument de la "fenêtre", un argument de plus local que mondial window de référence et le code à l'intérieur de cette fermeture va utiliser. Le window à la fin spécifie en fait ce qu'il faut passer pour le premier argument, dans ce cas le sens actuel de window ...l'espoir est que vous n'avez pas foiré window avant que cela arrive.

cela peut être plus facile à penser en montrant le cas le plus typique utilisé dans jQuery, plugin .noConflict() manipulation, donc pour la majorité du code, vous pouvez toujours utiliser $ , même si cela signifie quelque chose autre que jQuery en dehors de cette portée:

(function($) {
  //inside here, $ == jQuery, it was passed as the first argument
})(jQuery);
5
répondu Nick Craver 2010-04-26 19:10:41

Testé avec 1000000 itérations. Ce type de localisation n'a aucun effet sur la performance. Pas même une milliseconde en 1000000 itérations. C'est tout simplement inutile.

5
répondu Semra 2012-03-11 15:19:52