Convertir une chaîne en nom de variable en JavaScript


260

J'ai cherché des solutions, mais je n'ai trouvé aucun résultat.

J'ai une variable appelée onlyVideo.

"onlyVideo"la chaîne est passée dans une fonction. Je veux définir la variable onlyVideoà l'intérieur de la fonction comme quelque chose. Comment puis je faire ça?

(Il y a un certain nombre de variables qui pourraient être appelées dans la fonction, donc j'en ai besoin pour fonctionner dynamiquement, pas des ifinstructions codées en dur .)

Edit: Il y a probablement une meilleure façon de faire ce que vous essayez de faire. Je l'ai demandé au début de mon aventure JavaScript. Découvrez comment fonctionnent les objets JavaScript.

Une introduction simple:

// create JavaScript object
var obj = { "key1": 1 };

// assign - set "key2" to 2
obj.key2 = 2;

// read values
obj.key1 === 1;
obj.key2 === 2;

// read values with a string, same result as above
// but works with special characters and spaces
// and of course variables
obj["key1"] === 1;
obj["key2"] === 2;

// read with a variable
var key1Str = "key1";
obj[key1Str] === 1;

5
Pourquoi utilisez-vous cela? Êtes-vous absolument sûr de devoir le définir sur une variable locale normale, et un objet (hachage) ne fonctionnera pas?
Dogbert

mmm ... Je ne comprends toujours pas pourquoi vous voulez faire ça dans un monde avec des tableaux. Quoi qu'il en soit, une partie de votre code et de vos explications vous serait très utile.
Kevin Chavez

je pense que nous avons besoin de plus de détails sur votre objectif ultime
mcgrailm

Réponses:


281

S'il s'agit d'une variable globale, alors window[variableName] ou dans votre cas window["onlyVideo"], faites l'affaire.


35
Même s'il n'est pas global, vous pouvez y accéder comme ça par scope[property]ou mêmethis[property]
Wojciech Bednarski

7
@WojciechBednarski: Ne confondez pas portée et contexte. thisest le contexte, ce qu'il pointe dépend de la façon dont la fonction est appelée. Dans JS, 50% du temps thisest à windowmoins que vous n'activiez le mode strict et thisdevienne undefinedet générera une erreur. La portée est quelque chose de complètement différent et ce n'est pas un objet (sauf la portée globale qui est reflétée par l' windowobjet)
slebetman

3
Ne fonctionne pas dans WebWorkers(où se selfréfère à la portée globale, tout comme dans le navigateur, où il est égal à window) et dans Node.js, où globalest la variable souhaitée. Et il fonctionne plus récemment avec des étendues locales, telles que le corps de la fonction.
Tomáš Zato - Rétablir Monica

est-il possible de définir un en constutilisant cette méthode?
toing_toing

165

Javascript a une eval()fonction pour de telles occasions:

function (varString) {
  var myVar = eval(varString);
  // .....
}

Edit: Désolé, je pense que j'ai survolé la question trop rapidement. Cela ne vous obtiendra que la variable, pour la définir, vous avez besoin

function SetTo5(varString) {
  var newValue = 5;
  eval(varString + " = " + newValue);
}

ou si vous utilisez une chaîne:

function SetToString(varString) {
  var newValue = "string";
  eval(varString + " = " + "'" + newValue + "'");
}

Mais j'imagine qu'il existe un moyen plus approprié d'accomplir ce que vous recherchez? Je ne pense pas que eval () soit quelque chose que vous voulez vraiment utiliser à moins qu'il y ait une bonne raison à cela. eval ()


3
Ouais j'irais avec cela plutôt qu'en utilisant la fenêtre (il y a quelques mises en garde)
ingo

12
Pourquoi une eval()réponse a- t-elle été rejetée à la suppression et celle-ci a-t-elle été votée?
BoltClock

4
@goggin Vous devez tester regex l'argument pour vous assurer qu'il s'agit d'un nom valide. Évaluer l'argument sans le vérifier au préalable est ridiculement peu sûr.
Šime Vidas

16
C'est la seule réponse réaliste à la question. Ce n'est pas parce qu'il impliquait l'évaluation "eeeeevil" que cela est moins vrai. Javascript n'a pas de variables variables (comme $$ varname en php) donc c'est vraiment la seule réponse. En utilisantwindow[varname] a pour effet secondaire d'introduire des variables globales, ce qui n'est peut-être pas souhaitable. @Shaz Je ne pense pas que vous accordiez suffisamment de crédit aux interprètes JS modernes. Ils sont extrêmement rapides, et l'analyse et l'exécution d'une simple opération d'affectation d'une ligne ne vont pas augmenter l'utilisation du processeur de quiconque tant que cela n'est pas fait dans un minuteur de 1 ms ou une boucle serrée.
MooGoo

2
@TheParamagneticCroissant Des gens passionnés par le soin du code. Ceux qui n'apprécient que le temps et l'argent ne le font pas.
Jimbo

41

En ce qui concerne eval vs solutions variables globales ...

Je pense qu'il y a des avantages pour chacun, mais c'est vraiment une fausse dichotomie. Si vous êtes paranoïaque de l'espace de noms global, créez simplement un espace de noms temporaire et utilisez la même technique.

var tempNamespace = {};
var myString = "myVarProperty";

tempNamespace[myString] = 5;

Je suis sûr que vous pourriez alors accéder en tant que tempNamespace.myVarProperty (maintenant 5), en évitant d'utiliser une fenêtre pour le stockage. (La chaîne peut également être placée directement entre crochets)


Un peu de refactoriser votre code pour faire la même var inline tempNamespace = {["myVarProperty"]: "Certainement que de la vidéo"};
Tioma

1
C'est une très bonne solution - il semble que eval () soit à éviter à moins que cela ne soit absolument nécessaire, une solution de contournement très élégante ici.
skwidbreth

En commençant par la collection document.body.getElementsByTagName ('*'), il est facile de trouver tous les éléments ayant un attribut 'id' et de créer une variable pour la valeur d'objet élément de chacun dans un objet global 'id'. Ensuite, vous pouvez vous référer à <div id = container> en JavaScript comme 'id.container'. Si facile!
David Spector

15
var myString = "echoHello";

window[myString] = function() {
    alert("Hello!");
}

echoHello();

Dites non au eval maléfique . Exemple ici: https://jsfiddle.net/Shaz/WmA8t/


3
Faites ce travail sur la portée locale et je supprimerai le downvote.
Tomáš Zato - Rétablir Monica

@ TomášZatofunction aScope() { this[myString] = function() { alert("Hello!"); };};
rrw

@richmondwang thisn'est pas une référence à la portée locale mais à l'objet auquel la fonction est liée pendant l'appel.
Tomáš Zato - Rétablir Monica le

8

Vous pouvez accéder à l'objet fenêtre en tant que tableau associatif et le définir de cette façon

window["onlyVideo"] = "TEST";
document.write(onlyVideo);

8

La méthode window ['variableName'] fonctionne UNIQUEMENT si la variable est définie dans la portée globale. La bonne réponse est "Refactor". Si vous pouvez fournir un contexte "Objet", une solution générale possible existe, mais il existe certaines variables qu'aucune fonction globale ne pourrait résoudre en fonction de la portée de la variable.

(function(){
    var findMe = 'no way';
})();

6

Si vous essayez d'accéder à la propriété d'un objet, vous devez commencer par la portée de windowet parcourir chaque propriété de l'objet jusqu'à ce que vous arriviez à celle que vous souhaitez. En supposant que cela a.b.ca été défini ailleurs dans le script, vous pouvez utiliser ce qui suit:

var values = window;
var str = 'a.b.c'.values.split('.');

for(var i=0; i < str.length; i++)
    values = values[str[i]];

Cela fonctionnera pour obtenir la propriété de n'importe quel objet, quelle que soit sa profondeur.


Votre exemple est cool. Je note que si j'utilise namecomme nom de variable, votre exemple échoue, mais il fonctionne avec d'autres noms de variables. Cela peut être dû au fait que l'objet Window possède déjà une namevariable. En outre, l'inclusion de la .valueméthode a provoqué un échec. La capacité d'interpréter des variables d'objets profondément imbriquées est ce que je recherche et votre méthode indique une bonne direction. Merci.
Theo

Aucun problème. La réponse est plus pour démontrer le concept plutôt que d'être une réponse copier / coller (comme le sont la plupart des réponses ici sur SO je pense)

1
Les réponses SO sont encore meilleures lorsque vous pouvez passer du temps à les améliorer plutôt qu'à les corriger. ;-)
Theo

Ne fonctionne pas:Uncaught TypeError: Cannot read property 'split' of undefined
Roberto14


0

Cela peut être fait comme ça

(function(X, Y) {
  
  // X is the local name of the 'class'
  // Doo is default value if param X is empty
  var X = (typeof X == 'string') ? X: 'Doo';
  var Y = (typeof Y == 'string') ? Y: 'doo';
  
  // this refers to the local X defined above
  this[X] = function(doo) {
    // object variable
    this.doo = doo || 'doo it';
  }
  // prototypal inheritance for methods
  // defined by another
  this[X].prototype[Y] = function() {
    return this.doo || 'doo';
  };
  
  // make X global
  window[X] = this[X];
}('Dooa', 'dooa')); // give the names here

// test
doo = new Dooa('abc');
doo2 = new Dooa('def');
console.log(doo.dooa());
console.log(doo2.dooa());


0

Le code suivant facilite la référence à chacun de vos DIV et autres éléments HTML en JavaScript. Ce code doit être inclus juste avant la balise, afin que tous les éléments HTML aient été vus. Il doit être suivi de votre code JavaScript.

// For each element with an id (example: 'MyDIV') in the body, create a variable
// for easy reference. An example is below.
var D=document;
var id={}; // All ID elements
var els=document.body.getElementsByTagName('*');
for (var i = 0; i < els.length; i++)
    {
    thisid = els[i].id;
    if (!thisid)
        continue;
    val=D.getElementById(thisid);
    id[thisid]=val;
    }

// Usage:
id.MyDIV.innerHTML="hello";

0

permettez-moi d'être plus clair

function changeStringToVariable(variable, value){
window[variable]=value
}
changeStringToVariable("name", "john doe");
console.log(name);
//this outputs: john doe
let file="newFile";
changeStringToVariable(file, "text file");
console.log(newFile);
//this outputs: text file

1
Bienvenue dans Stack Overflow! Bien que ce code puisse résoudre la question, y compris une explication de comment et pourquoi cela résout le problème aiderait vraiment à améliorer la qualité de votre message, et entraînerait probablement plus de votes positifs. N'oubliez pas que vous répondrez à la question des lecteurs à l'avenir, pas seulement à la personne qui pose la question maintenant. Veuillez modifier votre réponse pour ajouter des explications et donner une indication des limitations et hypothèses applicables.
Daniil
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.