114 votes

clés dynamiques pour les littéraux d'objets en Javascript

Ok, je travaille sur un projet en Nodes, et j'ai rencontré un petit problème avec les clés dans les objets littéraux, j'ai la configuration suivante :

var required = {
    directories : {
        this.applicationPath                    : "Application " + this.application + " does not exists",
        this.applicationPath + "/configs"       : "Application config folder does not exists",
        this.applicationPath + "/controllers"   : "Application controllers folder does not exists",
        this.applicationPath + "/public"        : "Application public folder does not exists",
        this.applicationPath + "/views"         : "Application views folder does not exists"
    },
    files : {
        this.applicationPath + "/init.js"               : "Application init.js file does not exists",
        this.applicationPath + "/controllers/index.js"  : "Application index.js controller file does not exists",
        this.applicationPath + "/configs/application.js": "Application configs/application.js file does not exists",
        this.applicationPath + "/configs/server.js"     : "Application configs/server.js file does not exists"
    }
}

Ok, beaucoup d'entre vous vont regarder ceci et penser que cela semble correct, mais le compilateur continue à me dire qu'il me manque un : (deux points), ce qui n'est pas le cas, il semble que l'option + ou et le . ont tous deux un effet sur le compilateur.

Je crois maintenant (je n'en suis pas sûr) que les objets littéraux sont créés au moment de la compilation et non de l'exécution, ce qui signifie que les variables dynamiques telles que this.applicationPath et la concaténation ne seront pas disponibles :( :(

Quelle est la meilleure façon de surmonter un tel obstacle sans avoir à réécrire de grandes parties du code ?

111voto

RobG Points 41170

Avant ECMAScript 2015 (ed 6), une clé littérale d'objet (ECMAScript l'appelle "initialisateur d'objet") doit être l'une des suivantes :

  1. Nom de l'identificateur
  2. Lettre d'identification de la chaîne
  3. NumériqueLittéral

Il n'est donc pas possible d'utiliser une expression comme clé dans un initialisateur. Cela a été modifié à partir d'ECMAScript 2015 (voir ci-dessous). Vous pouvez utiliser une expression avec la notation crochet pour accéder à une propriété, donc pour définir les propriétés avec une expression, vous devez faire :

var required = { directories : {}};
required.directories[this.applicationPath] = "Application " + this.application + " does not exists";
required.directories[this.applicationPath + "/configs"] = "Application config folder does not exists";
...

et ainsi de suite. Depuis le this.applicationPath est souvent réutilisé, il est préférable de stocker une référence pour améliorer les performances et réduire la quantité de code :

var a = this.applicationPath;
var required = { directories : {}};
var rd = required.directories;
rd[a] = "Application " + this.application + " does not exists";
rd[a + "/configs"] = "Application config folder does not exists";
...

Editar

Depuis ECMAScript 2015 (ed 6), les initialisateurs d'objets peuvent avoir des clés calculées en utilisant :

[expression]: value

Il existe également une syntaxe abrégée pour les noms de propriétés et de méthodes.

Véase MDN : Initialisateur d'objets o Initialisateur d'objets ECMAScript .

46voto

Felix Kling Points 247451

Vous pouvez définir des clés dynamiques en utilisant la notation entre crochets :

required.directories[this.applicationPath + "/configs"] = "Application config folder does not exists";

(bien entendu, quel que soit l'endroit où vous faites cette définition, this.applicationPath doit exister)

Mais avez-vous besoin this.applicationPath dans les clés ? Comment accédez-vous à ces valeurs ? Peut-être pouvez-vous simplement supprimer this.applicationPath de la valeur utilisée pour accéder aux propriétés.


Mais au cas où vous en auriez besoin :

Vous pouvez utiliser un tableau pour initialiser les clés si vous voulez éviter de répéter beaucoup de code :

var dirs = ['configs', 'controllers', ...];
var files = ['init.js', 'controllers/index.js', ...];

var required = { directories: {}, files: {} };
required.directories[this.applicationPath] = "Application " + this.application + " does not exists";

for(var i = dirs.length; i--;) {
    required.directories[this.applicationPath + '/' + dirs[i]] = "Application " + dirs[i] + " folder does not exists";
}

for(var i = files.length; i--;) {
    // same here
}

2voto

MooGoo Points 11094

Pour les littéraux d'objets, Javascript/ECMAScript script spécifie que les clés sont soit un IdentifierName valide, soit un littéral de chaîne, soit un nombre. crédit RobG (hexagone pair) . Pas une expression, qui est ce que required.applicationPath + "/configs" est.

0voto

japrescott Points 1944

Le problème vient de l'utilisation de "ceci" qui ne fait pas référence à quelque chose d'intelligent*. créer le littéral statique avec le chemin d'accès à l'application.

var required={
    "applicationPath":"someWhereOverTheRainboW"
};

Ensuite, utilisez

required.directories={};
required.directories\[required.applicationPath + "/configs"\]="Application config folder does not exists";
....

pour le remplir dynamiquement

Editer ; J'ai précipité ma première idée, elle n'a pas fonctionné. L'idée ci-dessus fonctionne maintenant - désolé pour cela !

* le mot clé 'this' est très intelligent :) mais il fait souvent référence à l'objet fenêtre ou à l'élément sur lequel l'événement a été déclenché ou à l'objet dit "actif". Ce qui crée beaucoup de confusion ;)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X