Qu’est-ce que ce code construit pour les parties d’une bibliothèque et à quoi cela sert-il?

J’ai imité une bibliothèque et j’ai pu écrire le code suivant. Ce code a créé 'c' object 'c' auquel 'a' fonction 'a' est affectée. Donc, pour appeler 'a' , je vais devoir écrire ca() .

De plus, j’ai pu append plus de fonctions à cet object 'c' . Je veux comprendre ce qui se passe dans ce code. Cela ne ressemble pas à une programmation orientée object normale. Comment appelle-t-on ce type de programmation JavaScript?

 var c = (function(c) { if (c === undefined) { c = {}; } function a() { alert(1); } ca = a; return c; }(c)); 

C’est un modèle de module. Vous verrez de nombreuses variantes de ce modèle, il est donc essentiel de comprendre ce qui se passe réellement, vous ne pouvez pas en imiter un seul.

Le but de ce morceau de code est de compléter un object c (généralement votre bibliothèque globale). Vous avez probablement beaucoup de morceaux de code similaires dans votre application, tous construisant des morceaux de c , probablement chacun de ceux-ci dans son propre fichier.

Si l’object bibliothèque c , qui est passé en argument à la fonction, n’existe pas encore ( c === undefined ), il est créé. Cela permet de ne pas dépendre de l’ordre d’exécution ou d’un fichier pré-exécuté.

La partie droite de l’affectation est une expression IIFE (expression de fonction immédiatement invoquée), c’est-à-dire une fonction appelée immédiatement. L’avantage de cette construction est qu’elle crée une scope dans laquelle les variables (par exemple, a fonction) peuvent être déclarées sans polluer la scope externe (globale). Ici, le point est discutable car il est externalisé de toute façon, mais un module dépend généralement de plusieurs fonctions et variables internes (privées).

Un détail qui pourrait nécessiter une explication: tous ces fichiers semblent définir une nouvelle variable c mais il n’y a pas de problème ici, même si les fichiers sont concaténés: une instruction var ne définit pas une nouvelle variable si elle existe déjà (une variable est défini pour l’ensemble du périmètre, ici globalement, même avant le sharepoint déclaration).

Une autre façon d’écrire cela aurait été

 var c = c || {}; // ensure the c variable is defined, and initialize its value it if necessary (function() { // let's use an IIFE to have a protected scope and not pollute the global one function a() { alert(1); } ca = a; // let's augment c })(); 

Celui-ci est probablement plus clair que

  • il sépare explicitement les deux étapes (initialisation c et complétion c par un IIFE)
  • il ne dépend pas de deux variables c portant le même nom
  • c’est moins verbeux

Voici le même code avec des commentaires supplémentaires sur ce que chaque ligne fait, et ce qui se passe quand nous le passons.

 //Here, we're defining a function that will return an object. //its only parameter is named 'c' //this is confusing, since the parameter has the same name as the global definition of the function. //the var c definition is the global definition. the function parameter is not. //so every reference to anything named 'c' inside the function definition is local. var c = (function(c) { //if c (the c we passed as a parameter) is not yet defined if (c === undefined) { //define c as an object c = {}; } //define a function function a() { alert(1); } //attach it to the object ca = a; //return the object return c; }(c)); // call the constructor we just defined, using the global definition of `c`. // the first time we pass this point, c as a variable is still undefined. 
 var c = (function(c) { if (c === undefined) { c = {}; } function a() { alert(1); } ca = a; return c; }(c)); 

Prenons le pas à pas.

var c =

initialiser une variable nommée c. Notez qu’à ce stade, si une variable nommée c est déjà initialisée, c se référerait à cette valeur uniquement jusqu’à la fin de cette déclaration.

( .... )

Cela signifie que tout ce qui est à l’intérieur doit être traité comme une expression.

function(c)

signifie que cette “expression” est une fonction qui prend un argument. Cet argument serait désormais désigné par le nom c jusqu’à ce que la fonction soit terminée. Toute variable avec le nom c qui a été déclaré en dehors de la scope de la fonction ne serait donc pas accessible directement ici. Bien que si elle se trouve dans la scope globale et que la scope globale se trouve être l’object de la fenêtre, elle peut être appelée window.c .

if (c === undefined) { ... }

vérifie si l’argument qui lui est transmis n’est pas défini ou non. Renvoie true si elle n’est pas définie, et exécute donc ce qui se trouve à l’intérieur du bloc if.

c = {}

définir la variable c sur un object vide. Donc, si l’argument était (passé ou) indéfini, nous le définissons nous-mêmes ici (et nous le définissons comme un object vide).

function a() { alert(1); }

déclaré une fonction avec le nom d’ a appel qui entraînera une alerte au chiffre 1. Notez qu’il ne s’agit que d’une déclaration de fonction. Nous n’avons pas encore appelé la fonction.

ca = a

L’argument c est maintenant assigné à une propriété nommée a qui fait référence à la fonction a nous venons de créer.

return c

sortir de la fonction avec la valeur de retour comme valeur finale de c , après avoir subi les modifications que nous avons apscopes à l’argument passé.

(fun...}(c))

appeler la fonction que nous venons de créer et lui passer en argument la valeur actuelle de c . comme nous avons appelé la fonction comme une expression, le résultat de cette expression serait la valeur de retour de la fonction. Et notre fonction retourne un object (que nous lui avons passé), après lui avoir assigné une propriété.

Puisque cette expression a été assimilée à la variable c , la valeur de retour de l’expression (qui est la valeur de retour de la fonction), est maintenant maintenue avec la variable c .

Si vous lisez tout cela correctement, vous saurez que la variable c contiendrait désormais un object, qui aurait une propriété a qui est une fonction qui alerte le numéro 1. Et cet object conserve également les propriétés qu’il aurait pu avoir auparavant.

Si nous déglutons ce code pour le rendre lisible simplement en rendant les noms de variables descriptifs:

 var myObject = (function(someObject) { if (someObject === undefined) { someObject = {}; } function alertOne () { alert(1); } someObject.alertOne = alertOne; return someObject; }(myObject)); 

Cette émission est un épisode du modèle révélateur du module de la série, qui indique comment append des propriétés supplémentaires à un object, qui a été déclaré précédemment, de manière élégante, sans polluer la scope globale. Mettant en vedette des expressions de fonction immédiatement invoquées (IIFE).

Pourquoi à la fin, nous avons écrit (c)) à nouveau?

C’est la fonction appelée immédiatement appelée .

 (function(received argument){ //some code here....... })(passed argument) //<-- here the function is invoked 

c est l'argument passé. La fonction est appelée immédiatement lorsqu'elle est créée. Ce type de déclaration permet de garder les variables privées et de conserver l’espace de noms global propre.

Le modèle dans votre code est utilisé pour créer des modules .

............ Maintenant, venez à votre code: ............

si l'argument passé n'est pas défini: .............

Tout d'abord, ...}(c)) cette partie de la fonction immédiatement invoquée est appelée. Elle est passée avec un argument appelé c qui n'est pas encore défini. (function(c){... partie reçoit cet argument c .

Ici, en premier lieu, l' passed argument c n'est pas if(c==undefined) Donc, if(c==undefined) est déclenché. À cet instant, en utilisant l'instruction c={} , l'object non défini c se voit atsortingbuer un empty object .

Ici, la function a() { //... } est une méthode privée créée dans un module. On ne peut pas y accéder globalement.

La méthode privée a is est rendue disponible globalement en l'atsortingbuant à c en utilisant ca=a déclaration. Ainsi, lorsque l'object retournera, vous pouvez appeler cette méthode sur un contexte global.

Ainsi, un object vide c nouvellement créé se voit atsortingbuer une méthode appelée a Ensuite, il retourne et var c reçoit cet object.

si l'argument passé n'est pas indéfini: ............

Mais si passed c n'est not undefined , si un object est passé, alors aucun nouvel object n'est créé. Cela signifie que if(c==undefined) est falsifié. Donc, il n'est pas exécuté. Je veux dire qu'aucun nouvel object vide n'est créé .Quand l'object Passed reçoit une nouvelle méthode appelée ca=a using ca=a

C'est simple comme ça.

Le code ci-dessous est une version beaucoup plus simple de votre code. Il enverra automatiquement un object vide s'il n'est pas défini au préalable . Ainsi, vous n'avez pas à prendre la peine de vérifier s'il n'est pas défini ou non. C'est ce que l'on appelle une augmentation en vrac.

 var c = (function(c) { function a() { alert(1); } ca = a; return c; }(c || {} )); 

Cet article écrit par Ben Cherry m’a aidé à comprendre ce type de modèle: http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html

Extrait de l’article:

Fermetures anonymes

Ceci est la construction fondamentale qui rend tout possible, et est vraiment la meilleure fonctionnalité de JavaScript. Nous allons simplement créer une fonction anonyme et l’exécuter immédiatement. Tout le code qui s’exécute à l’intérieur de la fonction réside dans une fermeture, qui assure la confidentialité et l’état pendant toute la durée de vie de notre application.

 (function () { // ... all vars and functions are in this scope only // still maintains access to all globals }()); 

Notez le () autour de la fonction anonyme. Ceci est requirejs par le langage, car les instructions commençant par la fonction de jeton sont toujours considérées comme des déclarations de fonction. Inclure () crée une expression de fonction à la place.

Import global

JavaScript a une fonctionnalité appelée globales implicites. Chaque fois qu’un nom est utilisé, l’interpréteur retourne la chaîne de scope à la recherche d’une instruction var pour ce nom. Si aucun n’est trouvé, cette variable est supposée être globale. S’il est utilisé dans une affectation, le global est créé s’il n’existe pas déjà. Cela signifie que l’utilisation ou la création de variables globales dans une fermeture anonyme est facile. Malheureusement, cela conduit à un code difficile à gérer, car il n’est pas évident (pour les humains) quelles variables sont globales dans un fichier donné.

Heureusement, notre fonction anonyme offre une alternative facile. En transmettant les globals comme parameters à notre fonction anonyme, nous les importons dans notre code, qui est à la fois plus clair et plus rapide que les globals implicites. Voici un exemple:

 (function ($, YAHOO) { // now have access to globals jQuery (as $) and YAHOO in this code }(jQuery, YAHOO)); 

Module d’exportation

Parfois, vous ne voulez pas simplement utiliser des globales, mais vous voulez les déclarer . Nous pouvons facilement le faire en les exportant, en utilisant la valeur de retour de la fonction anonyme. Cela complétera le modèle de base du module, voici donc un exemple complet:

 var MODULE = (function () { var my = {}, privateVariable = 1; function privateMethod() { // ... } my.moduleProperty = 1; my.moduleMethod = function () { // ... }; return my; }()); 

Notez que nous avons déclaré un module global nommé MODULE , avec deux propriétés publiques: une méthode nommée MODULE.moduleMethod et une variable nommée MODULE.moduleProperty . En outre, il maintient un état interne privé en utilisant la fermeture de la fonction anonyme. En outre, nous pouvons facilement importer les globales nécessaires, en utilisant le modèle que nous avons appris ci-dessus

Ce que vous faites, c’est déclarer une fonction anonyme, puis l’appeler avec un paramètre appelé c et l’assigner à une variable appelée aussi c , ce qui est très déroutant 🙂

Renommer les variables c’est ce que vous avez:

 var result=(function (input_parameter){...} (parameter_used_to_call_my_function)); 

Le dernier (c) vous parlez est le paramètre pour appeler la fonction. Il est plus facile de voir si vous utilisez une syntaxe plus longue:

 var my_function=function(input_parameter){...}; var result=my_function(result); 

Il est également intéressant de noter que vous appelez my_function utilisant result (bien que vous ayez appelé c ) en tant que paramètre, qui est également le nom de la variable que vous venez de créer pour stocker la valeur de retour de la fonction. JS est d’accord avec cela car il n’est pas ssortingct avec la façon dont vous manipulez les variables, mais c’est une façon déroutante d’écrire du code. Vous déclarez une variable et la transmettez (la variable avec ce nom, qui à ce point ne devrait pas exister) comme paramètre à votre fonction au cas où elle serait déclarée plus tôt (et en prenant soin de cette casse au sein de la fonction, au moins est consistent).

Ce qui se passe à l’intérieur de my_function c’est que vous vérifiez que votre paramètre a une valeur précédente (ce que j’ai expliqué si le paragraphe précédent); si ce n’était pas défini, vous l’initialisez à un object vide. Ensuite, vous ajoutez la fonction à input_parameter et la renvoyez.

Je ne sais pas s’il y a un nom pour ce type de programmation, mais utiliser le même nom de variable pour différentes choses ne semble pas être une bonne idée 🙂