Maison  >  Article  >  interface Web  >  Analyse approfondie de la programmation de modèles de modules JavaScript

Analyse approfondie de la programmation de modèles de modules JavaScript

coldplay.xixi
coldplay.xixiavant
2020-07-29 17:32:282988parcourir

Analyse approfondie de la programmation de modèles de modules JavaScript

Bases

Nous devons d'abord avoir un aperçu du modèle de module (blogué par Eric Miraglia de YUI dans 2007 proposé), si vous êtes déjà familier avec le mode Module, vous pouvez sauter cette section et lire directement "Mode Avancé".

Recommandations d'apprentissage associées : Tutoriel vidéo javascript

Fermeture de fonction anonyme

Fermeture de fonction anonyme sont la meilleure fonctionnalité de JavaScript, sans exception, ils rendent tout possible. Créons maintenant une fonction anonyme et exécutons-la immédiatement. Tout le code de la fonction est exécuté lors d'une fermeture, et la fermeture détermine la confidentialité et le statut de ces codes pendant tout le processus d'exécution.

Le code est le suivant :

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

Notez les parenthèses en dehors de la fonction anonyme. En effet, les instructions commençant par function en JavaScript sont généralement considérées comme des déclarations de fonction. L'ajout de parenthèses extérieures crée une expression de fonction.

Importation globale

JavaScript possède une fonctionnalité appelée variables globales cachées. Lorsqu'un nom de variable est utilisé, le compilateur recherchera l'instruction en utilisant var pour déclarer la variable. Si elle n'est pas trouvée, la variable est considérée comme globale. S'il est utilisé ainsi lors de l'affectation, une portée globale sera créée. Cela signifie qu'il est très simple de créer une variable globale dans une fermeture anonyme. Malheureusement, cela peut conduire à un code ingérable car le programmeur ne sait pas si les variables globales ne sont pas déclarées dans un fichier. Heureusement, les fonctions anonymes nous offrent une autre option. Nous pouvons importer des variables globales dans notre code via les paramètres de fonctions anonymes, ce qui est plus rapide et plus soigné.

Le code est le suivant :

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

Export de module

Parfois, vous ne souhaitez pas utiliser de variables globales, mais vous souhaitez pour les déclarer. Nous pouvons facilement les exporter grâce à la valeur de retour de fonctions anonymes. Voilà pour le contenu de base du modèle Module, voici un exemple plus compliqué.

Le code est le suivant :

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

Ici, nous déclarons un module global appelé MODULE, qui possède deux propriétés publiques : une méthode appelée MODULE.moduleMethod et une variable appelée MODULE.moduleProperty. De plus, il maintient un état interne privé grâce à la fermeture des fonctions anonymes. Bien entendu, nous pouvons également utiliser le mode mentionné précédemment pour importer facilement les variables globales requises

Mode avancé

.

Ce que j'ai mentionné précédemment est suffisant pour de nombreux besoins, mais nous pouvons approfondir ce modèle pour créer de puissantes structures évolutives. Continuons à apprendre à travers ce module appelé MODULE, petit à petit.

Extension

Actuellement, une limitation du mode module est que l'intégralité du module doit être écrite dans un seul fichier. Tous ceux qui ont développé du code à grande échelle connaissent l'importance de séparer un fichier en plusieurs fichiers. Heureusement, nous disposons d'un excellent moyen d'étendre les modules. Nous importons d’abord un module, puis ajoutons des attributs et enfin l’exportons. L'exemple ici est d'étendre MODULE en utilisant la méthode mentionnée ci-dessus.

Le code est le suivant :

var MODULE = (function (my) {
 my.anotherMethod = function () {
  // added method...
 };
 return my;
}(MODULE));

Bien qu'inutile, par souci de cohérence, nous utilisons à nouveau le mot-clé var. Ensuite, le code est exécuté et le module ajoutera une méthode publique appelée MODULE.anotherMethod. Le fichier d'extension conserve également son propre état interne privé et ses importations.

Extension lâche

Notre exemple ci-dessus nous oblige à créer d'abord le module, puis à développer le module. Ce n'est pas nécessaire. Le chargement de scripts de manière asynchrone est l'un des meilleurs moyens d'améliorer les performances de vos applications Javascript. . Grâce à une expansion libre, nous créons des modules flexibles qui peuvent être chargés dans n'importe quel ordre et divisés en plusieurs fichiers. La structure de chaque fichier est à peu près la suivante

Le code est le suivant :

var MODULE = (function (my) {
 // add capabilities...
 return my;
}(MODULE || {}));

Dans ce mode, l'instruction var est requise. Si le module importé n'existe pas, il sera créé. Cela signifie que vous pouvez utiliser des outils comme LABjs pour charger ces fichiers de modules en parallèle.

Extension étroite

Bien qu'une expansion lâche soit excellente, elle ajoute également certaines limitations à votre module. Le point le plus important est que vous n'avez aucun moyen de remplacer en toute sécurité les attributs du module et que vous ne pouvez pas utiliser les attributs du module dans d'autres fichiers pendant l'initialisation (mais vous pouvez les utiliser pendant l'exécution après l'initialisation). L'extension compacte inclut un certain ordre de chargement, mais prend en charge la réécriture. Voici un exemple (extension de notre MODULE d'origine).

Le code est le suivant :

var MODULE = (function (my) {
 var old_moduleMethod = my.moduleMethod;
 my.moduleMethod = function () {
  // method override, has access to old through old_moduleMethod...
 };
 return my;
}(MODULE));

Ici, nous avons réécrit MODULE.moduleMethod et conservé la référence à la méthode d'origine comme requis.

Copie et héritage

Le code est le suivant :

var MODULE_TWO = (function (old) {
 var my = {},
  key;
 for (key in old) {
  if (old.hasOwnProperty(key)) {
   my[key] = old[key];
  }
 }
 var super_moduleMethod = old.moduleMethod;
 my.moduleMethod = function () {
  // override method on the clone, access to super through super_moduleMethod
 };
 return my;
}(MODULE));

这种模式可能是最不灵活的选择。虽然它支持了一些优雅的合并,但是代价是牺牲了灵巧性。在我们写的代码中,那些类型是对象或者函数的属性不会被复制,只会以一个对象的两份引用的形式存在。一个改变,另外一个也改变。对于对象来说[g5] ,我们可以通过一个递归的克隆操作来解决,但是对于函数是没有办法的,除了eval。然而,为了完整性我还是包含了它。

跨文件的私有状态

把一个module分成多个文件有一很大的局限,就是每一个文件都在维持自身的私有状态,而且没有办法来获得其他文件的私有状态。这个是可以解决的,下面这个松拓展的例子,可以在不同文件中维持私有状态。

代码如下:

var MODULE = (function (my) {
 var _private = my._private = my._private || {},
  _seal = my._seal = my._seal || function () {
   delete my._private;
   delete my._seal;
   delete my._unseal;
  },
  _unseal = my._unseal = my._unseal || function () {
   my._private = _private;
   my._seal = _seal;
   my._unseal = _unseal;
  };
 // permanent access to _private, _seal, and _unseal
 return my;
}(MODULE || {}));

每一个文件可以为它的私有变量_private设置属性,其他文件可以立即调用。当module加载完毕,程序会调用MODULE._seal(),让外部没有办法接触到内部的 _.private。如果之后module要再次拓展,某一个属性要改变。在载入新文件前,每一个文件都可以调用_.unsea(),,在代码执行之后再调用_.seal。

这个模式在我今天的工作中想到的,我从没有在其他地方见到过。但是我认为这是一个很有用的模式,值得单独写出来。

Sub-modules

最后一个高级模式实际上是最简单的,有很多创建子module的例子,就像创建一般的module一样的。

代码如下:

MODULE.sub = (function () 
{ var my = {}; //
    ...
 return my;}());

虽然这可能是很简单的,但是我决定这值得被写进来。子module有一般的module所有优质的特性,包括拓展和私有状态。

总结

大多数高级模式都可以互相组合来创建更有用的新模式。如果一定要让我提出一个设计复杂应用的方法的话,我会结合松拓展,私有状态,和子module。

在这里我没有提到性能相关的事情,但是我可以说,module模式对于性能的提升有好处。它可以减少代码量,这就使得代码的载入更迅速。松拓展使得并行加载成为可能,这同样提升的载入速度。初始化的时间可能比其他的方法时间长,但是这多花的时间是值得的。只要全局变量被正确导入了运行的时候就不会出问题,在子module中由于对变量的引用链变短了可能也会提升速度。

最后,这是一个子module自身动态加载的例子(如果不存在就创建),为了简介我没有考虑内部状态,但是即便考虑它也很简单。这个模式可以让复杂,多层次的代码并行的加载,包括子module和其他所有的东西。

代码如下:

var UTIL = (function (parent, $) {
 var my = parent.ajax = parent.ajax || {};
 my.get = function (url, params, callback) {
  // ok, so I'm cheating a bit 
  return $.getJSON(url, params, callback);
 };
 // etc...
 return parent;
}(UTIL || {}, jQuery));

我希望这些内容是有用的,请在下面留言来分享你的想法。少年们,努力吧,写出更好的,更模块化的JavaScript。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer