web-dev-qa-db-fra.com

Utiliser des noms de variables dynamiques en JavaScript

Dans PHP, vous pouvez faire des choses incroyables/horribles comme ceci:

$a = 1;
$b = 2;
$c = 3;
$name = 'a';
echo $$name;
// prints 1

Est-il possible de faire quelque chose comme ça avec Javascript?

Par exemple. si j'ai un var name = 'the name of the variable'; puis-je obtenir une référence à la variable nommée name?

313
Finbarr

Comme ECMA-/Javascript est tout à propos de Objects et Contexts (qui sont aussi une sorte d’objet), chaque variable est stockée dans un tel appelé Variable - (ou au cas où d'une fonction, objet d'activation).

Donc, si vous créez des variables comme celle-ci:

var a = 1,
    b = 2,
    c = 3;

Dans le portée globale (= le contexte de la fonction NO), vous écrivez implicitement ces variables dans le objet global (= window d'un navigateur).

Ceux-ci peuvent être accédés en utilisant la notation "point" ou "crochet":

var name = window.a;

ou

var name = window['a'];

Ceci ne fonctionne que pour l'objet global dans ce cas particulier, car l'objet objet variable de l'objet objet global est l'objet window lui-même. Dans le contexte d'une fonction, vous n'avez pas d'accès direct à l'objet objet d'activation. Par exemple:

function foobar() {
   this.a = 1;
   this.b = 2;

   var name = window['a']; // === undefined
   alert(name);
   name = this['a']; // === 1
   alert(name);
}

new foobar();

new crée une nouvelle instance d'un objet auto-défini (contexte). Sans new l'étendue de la fonction serait également global (= fenêtre). Cet exemple alerterait undefined et 1 respectivement. Si nous remplacions this.a = 1; this.b = 2 par:

var a = 1,
    b = 2;

Les deux sorties d'alerte seraient indéfinies. Dans ce scénario, les variables a et b seraient stockées dans l'objet d'activation à partir de foobar, auquel nous ne pouvons pas accéder (bien sûr, nous pourrions accéder à celles-ci directement en appelant a et b).

324
jAndy

eval est une option.

var a = 1;
var name = 'a';

document.write(eval(name)); // 1
143
erickb

Vous pouvez utiliser l'objet window pour y accéder.

window['myVar']

window contient une référence à toutes les variables globales et fonctions globales que vous utilisez.

74
JohnP

Mais je ne sais pas quelle mauvaise réponse obtient autant de votes. C'est une réponse assez facile mais vous le rendez complexe.

// If you want to get article_count
// var article_count = 1000;
var type = 'article';
this[type+'_count'] = 1000;  // in a function we use "this";
alert(article_count);
36
Terry Lin
a = 'varname';
str = a+' = '+'123';
eval(str)
alert(varname);

Essaye ça...

28
amitchd

Ceci est un exemple :

for(var i=0; i<=3; i++) {
    window['p'+i] = "hello " + i;
}

alert(p0); // hello 0
alert(p1); // hello 1
alert(p2); // hello 2
alert(p3); // hello 3

Un autre exemple :

var myVariable = 'coco';
window[myVariable] = 'riko';

alert(coco); // display : riko

Ainsi, la valeur " coco " de myVariable devient une variable coco.

Car toutes les variables de la portée globale sont des propriétés de l'objet Window.

24
Azodium

En Javascript, vous pouvez utiliser le fait que toutes les propriétés sont des paires clé-valeur. jAndy a déjà mentionné cela, mais je ne pense pas que sa réponse montre comment il peut être exploité.

Généralement, vous n'essayez pas de créer une variable pour contenir un nom de variable, mais vous essayez de générer des noms de variables, puis de les utiliser. PHP le fait avec la notation $$var mais Javascript n'est pas nécessaire car les clés de propriété sont interchangeables avec les clés de tableau.

var id = "abc";
var mine = {};
mine[id] = 123;
console.log(mine.abc);

donne 123. Habituellement, vous voulez construire la variable, raison pour laquelle il existe un indirection, vous pouvez également le faire à l'inverse.

var mine = {};
mine.abc = 123;
console.log(mine["a"+"bc"]);
12
David Newcomb

Si vous ne souhaitez pas utiliser d'objet global tel que window ou global (noeud), vous pouvez essayer quelque chose comme ceci:

var obj = {};
obj['whatever'] = 'There\'s no need to store even more stuff in a global object.';

console.log(obj['whatever']);
4
Brent Barbata

2019

TL; DR

  • eval peut exécuter une expression de chaîne dans le contexte qu'il a appelé et renvoyer des variables à partir de ce contexte;
  • literal object peut théoriquement le faire en écrivant: {[varName]}, mais il est bloqué par définition.

Donc, je tombe sur cette question et tout le monde ici joue juste sans apporter de vraie solution. mais @Axel Heider a une bonne approche.

La solution est eval. opérateur presque le plus oublié. (pense que la plupart est with())

eval peut exécuter une expression de manière dynamique dans le contexte qu'il a appelé. et renvoyer le résultat de cette expression. nous pouvons l'utiliser pour renvoyer dynamiquement la valeur d'une variable dans le contexte de la fonction.

exemple:

function exmaple1(){
   var a = 1, b = 2, default = 3;
   var name = 'a';
   return eval(name)
}

example1() // return 1


function example2(option){
  var a = 1, b = 2, defaultValue = 3;

  switch(option){
    case 'a': name = 'a'; break;
    case 'b': name = 'b'; break;
    default: name = 'defaultValue';
  }
  return eval (name);
}

example2('a') // return 1
example2('b') // return 2
example2() // return 3

Notez que j'écris toujours explicitement l'expression eval s'exécutera. Pour éviter des surprises inutiles dans le code. eval est très fort Mais je suis sûr que vous le savez déjà

BTW, s’il était légal, nous pourrions utiliser literal object pour capturer le nom et la valeur de la variable, mais nous ne pouvons pas combiner les noms de propriété calculés et la valeur de la propriété, ce qui est malheureusement invalide.

functopn example( varName ){
    var var1 = 'foo', var2 ='bar'

    var capture = {[varName]}

}

example('var1') //trow 'Uncaught SyntaxError: Unexpected token }`
3
pery mimon

J'avais besoin de dessiner plusieurs FormData à la volée et la manière de travailler a bien fonctionné

var forms = {}

Ensuite, dans mes boucles, là où j'avais besoin de créer un formulaire de données que j'ai utilisé

forms["formdata"+counter]=new FormData();
forms["formdata"+counter].append(var_name, var_value);
2
Talha

ce qu'ils veulent dire, c'est non, vous ne pouvez pas. il n'y a aucun moyen de le faire. il était donc possible de faire quelque chose comme ça

function create(obj, const){
// where obj is an object and const is a variable name
function const () {}

const.prototype.myProperty = property_value;
// .. more prototype

return new const();

}

ayant une fonction de création identique à celle implémentée dans ECMAScript 5.

1
Alfgaar

eval () n'a pas fonctionné dans mes tests. Mais l'ajout d'un nouveau code JavaScript à l'arborescence DOM est possible. Donc, voici une fonction qui ajoute une nouvelle variable:

function createVariable(varName,varContent)
{
  var scriptStr = "var "+varName+"= \""+varContent+"\""

  var node_scriptCode = document.createTextNode( scriptStr )
  var node_script = document.createElement("script");
  node_script.type = "text/javascript"
  node_script.appendChild(node_scriptCode);

  var node_head = document.getElementsByTagName("head")[0]
  node_head.appendChild(node_script);
}

createVariable("dynamicVar", "some content")
console.log(dynamicVar)
1
Axel Heider

Bien que cela ait une réponse acceptée, je voudrais ajouter une observation:

Dans ES6, en utilisant letne fonctionne pas:

/*this is NOT working*/
let t = "skyBlue",
    m = "gold",
    b = "tomato";

let color = window["b"];
console.log(color);

Cependant, en utilisant varfonctionne

/*this IS working*/
var t = "skyBlue",
    m = "gold",
    b = "tomato";

let color = window["b"];
console.log(color);

J'espère que cela pourra être utile à certains.

0
enxaneta

utiliser Object is great too.

var a=123
var b=234
var temp = {"a":a,"b":b}
console.log(temp["a"],temp["b"]);
0
Steve Jiang

C'est une alternative pour ceux qui ont besoin d'exporter une variable nommée dynamiquement

export {
  [someVariable]: 'some value',
  [anotherVariable]: 'another value',
}

// then.... import from another file like this:
import * as vars from './some-file'

Une autre alternative est de simplement créer un objet dont les clés sont nommées dynamiquement

const vars = { [someVariable]: 1, [otherVariable]: 2 };

// consume it like this
vars[someVariable];
0
JeanAlesi