Existe-t-il une manière « concise » de créer un espace de noms en JavaScript ?

StackOverflow https://stackoverflow.com/questions/13021

  •  08-06-2019
  •  | 
  •  

Question

J'ai fréquemment rencontré des sites qui mettaient tout leur JavaScript dans un namespace une structure qui s'articule autour de :

namespaces = { com : { example: { example.com's data} }

Cependant, sa configuration en toute sécurité par rapport à d'autres frameworks avec espace de noms semble nécessiter une quantité de code relativement importante (définie comme > 2 lignes).Je me demandais si quelqu'un connaissait une manière concise de procéder ?De plus, existe-t-il une manière relativement standard/cohérente de le structurer ?Par exemple, est-ce que com espace de noms directement attaché à l'objet global, ou est-il attaché via un objet espace de noms ?

[Modifier:oups, évidemment {com = { ... } } n'accomplirait rien de proche de ce que j'avais prévu, merci à Shog9 de l'avoir signalé.]

Était-ce utile?

La solution

Javascript n'a pas d'espaces de noms autonomes.Il possède des fonctions qui peuvent permettre de résoudre des noms, et des objets qui peuvent contribuer aux données nommées accessibles dans une portée donnée.

Voici votre exemple, corrigé :

var namespaces = { com: { example: { /* example.com's data */ } } }

Ceci est une variable namespaces se voir attribuer un objet littéral.L'objet contient une propriété : com, un objet avec une propriété : example, un objet qui contiendrait vraisemblablement quelque chose d'intéressant.

Donc, vous pouvez taper quelque chose comme espaces de noms.com.exemple.somePropertyOrFunctionOnExample et tout fonctionnera.Bien sûr, c'est aussi ridicule.Vous n'avez pas d'espace de noms hiérarchique, vous avez un objet contenant un objet contenant un objet avec les éléments qui vous intéressent réellement.

var com_example_data = { /* example.com's data */ };

Cela fonctionne tout aussi bien, sans la hiérarchie inutile.

Maintenant, si en fait tu vouloir pour construire une hiérarchie, vous pouvez essayer quelque chose comme ceci :

com_example = com_example || {};
com_example.flags = com_example.flags || { active: false, restricted: true};

com_example.ops = com_example.ops || (function()
    {
       var launchCodes = "38925491753824"; // hidden / private
       return {
         activate: function() { /* ... */ },
         destroyTheWorld: function() { /* ... */ }
       };
    })();

... ce qui est, à mon humble avis, raisonnablement concis.

Autres conseils

Voici un article intéressant de Peter Michaux sur Espace de noms Javascript.Il discute de 3 types différents d'espace de noms Javascript :

  1. Espacement de noms de préfixe
  2. Espacement de noms d'objet unique
  3. Espacement de noms d'objets imbriqués

Je ne plagierai pas ce qu'il a dit ici mais je pense que son article est très instructif.

Peter est même allé jusqu'à souligner que certains d'entre eux présentent des problèmes de performances.Je pense que ce sujet serait intéressant à aborder étant donné que les nouveaux plans ECMAScript Harmony ont abandonné les plans 4.0 pour l'espace de noms et l'empaquetage.

J'essaie de suivre la convention Yahoo consistant à créer un objet parent unique dans la portée globale pour tout contenir ;

var FP = {};
FP.module = {};
FP.module.property = 'foo';

Pour vous assurer de ne pas écraser un objet existant, vous devriez faire quelque chose comme :

if(!window.NameSpace) {
    NameSpace = {};
}

ou

var NameSpace = window.NameSpace || {};

De cette façon, vous pouvez le placer en haut de chaque fichier de votre application/site Web sans vous soucier de l'écrasement de l'objet espace de noms.Cela vous permettrait également d'écrire des tests unitaires pour chaque fichier individuellement.

Le Bibliothèque YUI La bibliothèque contient du code qui gère l'espace de noms à l'aide d'une fonction que vous trouverez peut-être préférable.D'autres bibliothèques peuvent également le faire.

Au lieu d'un point ou d'un trait de soulignement, vous pouvez utiliser le signe dollar :

var namespaces$com$example = "data"; 

J'aime aussi ça (source):

(function() {
    var a = 'Invisible outside of anonymous function';
    function invisibleOutside() {
    }

    function visibleOutside() {
    }
    window.visibleOutside = visibleOutside;

    var html = '--INSIDE Anonymous--';
    html += '<br/> typeof invisibleOutside: ' + typeof invisibleOutside;
    html += '<br/> typeof visibleOutside: ' + typeof visibleOutside;
    contentDiv.innerHTML = html + '<br/><br/>';
})();

var html = '--OUTSIDE Anonymous--';
html += '<br/> typeof invisibleOutside: ' + typeof invisibleOutside;
html += '<br/> typeof visibleOutside: ' + typeof visibleOutside;
contentDiv.innerHTML += html + '<br/>';​

Utilisez un objet littéral et soit le this objet ou le nom explicite pour effectuer un espacement de noms basé sur les propriétés frères et sœurs de la variable locale qui contient la fonction.Par exemple:

var foo = { bar: function(){return this.name; }, name: "rodimus" }
var baz = { bar: function(){return this.name; }, name: "optimus" }

console.log(foo.bar());
console.log(baz.bar());

Ou sans l'explicite name propriété:

var foo = { bar: function rodimus(){return this; } }
var baz = { bar: function optimus(){return this; } }

console.log(foo.bar.name);
console.log(baz.bar.name);

Ou sans utiliser this:

var foo = { bar: function rodimus(){return rodimus; } }
var baz = { bar: function optimus(){return optimus; } }

console.log(foo.bar.name);
console.log(baz.bar.name);

Utilisez le RegExp ou Object fonctions de constructeur pour ajouter des propriétés de nom aux variables de compteur et autres noms communs, puis utilisez un hasOwnProperty test pour faire vérification:

 var foo = RegExp(/bar/);
 
/* Add property */
foo.name = "alpha";

document.body.innerHTML = String("<pre>" + ["name", "value", "namespace"] + "</pre>").replace(/,/g, "&#09;");

/* Check type */
if (foo.hasOwnProperty("name")) 
  {
  document.body.innerHTML += String("<pre>" + ["foo", String(foo.exec(foo)), foo.name] + "</pre>").replace(/,/g, "&#09;");
  }

/* Fallback to atomic value */
else 
  {
  foo = "baz";
  }

var counter = Object(1);

/* Add property */
counter.name = "beta";

if (counter.hasOwnProperty("name")) 
  {
  document.body.innerHTML += String("<pre>" + ["counter", Number(counter), counter.name] + "</pre>").replace(/,/g, "&#09;");
  } 
else 
  {
  /* Fallback to atomic value */
  counter = 0;
  }

Le DOM utilise la convention suivante pour les définitions d'interface d'espace de noms HTML et d'éléments SVG :

  • ÉlémentTitreHTML
  • ÉlémentTitreSVG
  • ÉlémentSVGScript
  • Élément HTMLScript

Le noyau JavaScript utilise des prototypes pour créer un espace de noms. toString méthode comme une forme simple de polymorphisme.

Les références

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top