Convertir cadena a nombre de variable en JavaScript


260

He buscado soluciones, pero no pude encontrar ninguna que funcione.

Tengo una variable llamada onlyVideo.

"onlyVideo"la cadena se pasa a una función. Quiero establecer la variable onlyVideodentro de la función como algo. ¿Cómo puedo hacer eso?

(Hay una serie de variables que podrían llamarse a la función, por lo que necesito que funcione dinámicamente, no ifdeclaraciones codificadas ).

Editar: Probablemente haya una mejor manera de hacer lo que intentas hacer. Lo pregunté al principio de mi aventura de JavaScript. Mira cómo funcionan los objetos JavaScript.

Una simple introducción:

// 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;

55
¿Para qué estás usando esto? ¿Está absolutamente seguro de que necesita establecerlo en una variable local normal y que un Objeto (Hash) no funcionará?
Dogbert

mmm ... Todavía no entiendo por qué quieres hacer esto en un mundo con matrices. De todos modos, parte de su código y explicación ayudarían mucho.
Kevin Chavez

Creo que necesitamos más detalles sobre cuál es su objetivo final
mcgrailm

Respuestas:


281

Si es una variable global, entonces window[variableName] o en su caso window["onlyVideo"]debería hacer el truco.


35
Incluso si no es global, puede acceder a él de esa manera scope[property]o inclusothis[property]
Wojciech Bednarski

77
@WojciechBednarski: No confunda el alcance y el contexto. thises el contexto, lo que apunta depende de cómo se llama la función. En JS, el 50% del tiempo thises a windowmenos que habilite el modo estricto y se thisconvierta undefinedy arroje un error. El alcance es algo completamente diferente y no es un objeto (excepto el alcance global que refleja el windowobjeto)
slebetman

3
No funciona en WebWorkers(donde se selfrefiere al alcance global, tal como lo hace en el navegador, donde es igual a window) y Node.js, donde globalestá la variable que desea. Y más reciente funciona con ámbitos locales, como el cuerpo de la función.
Tomáš Zato - Restablece a Mónica el

¿hay alguna forma de definir un constuso de este método?
toing_toing

165

Javascript tiene una eval()función para tales ocasiones:

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

Editar: Lo siento, creo que leí la pregunta demasiado rápido. Esto solo te dará la variable, para configurarla necesitas

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

o si usa una cadena:

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

Pero me imagino que hay una manera más apropiada de lograr lo que estás buscando. No creo que eval () sea algo que realmente quieras usar a menos que haya una buena razón para ello. eval ()


3
Sí, preferiría esto en lugar de usar window (tiene algunas advertencias)
Ingo

12
¿Por qué se eval()rechazó una respuesta a eliminación, y esta se votó a favor?
BoltClock

44
@goggin Deberías probar el argumento con expresiones regulares para asegurarte de que sea un nombre válido. Simplemente evaluar el argumento sin verificarlo primero es ridículamente inseguro.
Šime Vidas

16
Esta es la única respuesta realista a la pregunta. El hecho de que involucrara la evaluación "eeeeevil" no lo hace menos cierto. Javascript no tiene variables variables (como $$ varname en php), por lo que esta es realmente la única respuesta. El uso window[varname]tiene el efecto secundario de introducir variables globales, que podrían no ser deseadas. @ Shaz No creo que le des suficiente crédito a los intérpretes modernos de JS. Son extremadamente rápidos, y analizar y ejecutar una operación simple de asignación de una línea no aumentará el uso de la CPU de nadie, siempre que no se realice en un temporizador de 1 ms o en un bucle cerrado.
MooGoo

2
@TheParamagneticCroissant Personas apasionadas por el cuidado de códigos. Los que solo valoran el tiempo y el dinero no lo hacen.
Jimbo

41

En cuanto a las soluciones eval vs. globales variables ...

Creo que hay ventajas para cada uno, pero esto es realmente una falsa dicotomía. Si eres paranoico del espacio de nombres global, solo crea un espacio de nombres temporal y usa la misma técnica.

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

tempNamespace[myString] = 5;

Bastante seguro de que podría acceder como tempNamespace.myVarProperty (ahora 5), ​​evitando usar la ventana para el almacenamiento. (La cadena también se puede poner directamente entre los corchetes)


Un poco refactorice su código para hacer la misma línea var tempNamespace = {["myVarProperty"]: "Definitivamente solo video"};
Tioma

1
Esta es una muy buena solución: parece que se debe evaluar eval () a menos que sea absolutamente necesario, una solución muy elegante aquí.
skwidbreth

Comenzando con la colección document.body.getElementsByTagName ('*') es fácil encontrar todos los elementos que tienen un atributo 'id' y crear una variable para el valor del objeto elemento de cada uno en un objeto 'id' global. Entonces puede referirse a <div id = container> en JavaScript como 'id.container'. ¡Tan fácil!
David Spector

15
var myString = "echoHello";

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

echoHello();

Di no al malvado eval. Ejemplo aquí: https://jsfiddle.net/Shaz/WmA8t/


3
Haga que esto funcione en el ámbito local y eliminaré el voto negativo.
Tomáš Zato - Restablece a Mónica el

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

@richmondwang thisno hace referencia al ámbito local, sino al objeto al que está vinculada la función durante la llamada.
Tomáš Zato - Restablece a Mónica el

8

Puede acceder al objeto de ventana como una matriz asociativa y configurarlo de esa manera

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

8

El método de la ventana ['variableName'] SOLO funciona si la variable se define en el ámbito global. La respuesta correcta es "Refactor". Si puede proporcionar un contexto de "Objeto", existe una posible solución general, pero hay algunas variables que ninguna función global podría resolver en función del alcance de la variable.

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

6

Si está intentando acceder a la propiedad de un objeto, debe comenzar con el alcance de windowy recorrer cada propiedad del objeto hasta llegar al que desea. Suponiendo que a.b.cse haya definido en otra parte del script, puede usar lo siguiente:

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

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

Esto funcionará para obtener la propiedad de cualquier objeto, sin importar cuán profundo sea.


Tu ejemplo es genial. Observo que si uso namecomo nombre de variable, su ejemplo falla, pero funciona con otros nombres de variables. Esto puede tener que ver con el objeto Window que ya tiene una namevariable. Además, incluir el .valuemétodo causó fallas. La capacidad de interpretar variables de objeto profundamente anidadas es lo que estoy buscando y su método indica una buena dirección. Gracias.
Theo

No hay problema. La respuesta es más para demostrar el concepto en lugar de ser una respuesta de copiar / pegar (como la mayoría de las respuestas aquí en SO, creo)

1
Las respuestas de SO son aún mejores cuando puede pasar el tiempo mejorándolas en lugar de arreglarlas. ;-)
Theo

No funciona:Uncaught TypeError: Cannot read property 'split' of undefined
Roberto14


0

Se puede hacer así

(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

El siguiente código facilita la referencia a cada uno de sus DIV y otros elementos HTML en JavaScript. Este código debe incluirse justo antes de la etiqueta, de modo que se hayan visto todos los elementos HTML. Debería ir seguido de su código 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

déjame aclararlo

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
¡Bienvenido a Stack Overflow! Si bien este código puede resolver la pregunta, incluir una explicación de cómo y por qué esto resuelve el problema realmente ayudaría a mejorar la calidad de su publicación, y probablemente resultaría en más votos positivos. Recuerde que está respondiendo la pregunta para los lectores en el futuro, no solo la persona que pregunta ahora. Por favor, editar su respuesta para agregar explicaciones y dar una indicación de lo que se aplican limitaciones y supuestos.
Daniil
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.