Converter string em nome de variável em JavaScript

260

Procurei soluções, mas não consegui encontrar nenhuma que funcionasse.

Eu tenho uma variável chamada onlyVideo.

"onlyVideo"a cadeia é passada para uma função. Eu quero definir a variável onlyVideodentro da função como algo. Como eu posso fazer isso?

(Há várias variáveis ​​que podem ser chamadas para a função, por isso preciso que ela funcione dinamicamente, não em ifinstruções codificadas .)

Edit: Provavelmente existe uma maneira melhor de fazer o que você está tentando fazer. Perguntei isso no início da minha aventura em JavaScript. Confira como os objetos JavaScript funcionam.

Uma introdução simples:

// 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;
Switz
fonte
5
Para que você está usando isso? Você tem certeza absoluta de que precisa configurá-lo para uma variável local normal e um Objeto (Hash) não funciona?
314 Dogbert
mmm ... Ainda não entendi por que você quer fazer isso em um mundo com matrizes. De qualquer forma, parte do seu código e explicação ajudariam muito.
21811 Kevin Chavez
Acho que precisamos de mais detalhes sobre o que seu objetivo final é
mcgrailm

Respostas:

280

Se é uma variável global, então window[variableName] ou no seu caso window["onlyVideo"]deve fazer o truque.

ingo
fonte
35
Mesmo se não global, você pode acessá-lo assim por scope[property]ou mesmothis[property]
Wojciech Bednarski
7
@WojciechBednarski: Não confunda escopo e contexto. thisé contexto, o que ele aponta depende de como a função é chamada. Em JS, 50% do tempo thisé, a windowmenos que você ative o modo estrito e thistorne undefined- se e lançará um erro. O escopo é algo completamente diferente e não é um objeto (exceto escopo global que é espelhada pelo windowobjeto)
slebetman
3
Não funciona WebWorkers(onde se selfrefere ao escopo global, exatamente como no navegador, onde é igual a window) e Node.js, onde globalé a variável que você deseja. E funciona mais recentemente com escopos locais, como o corpo da função.
Tomáš Zato - Restabelecer Monica
existe alguma maneira de definir um constusando esse método?
toing_toing
165

Javascript tem uma eval()função para essas ocasiões:

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

Edit: Desculpe, eu acho que deslizei a pergunta muito rapidamente. Isso só lhe dará a variável, para configurá-la você precisa

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

ou se estiver usando uma string:

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

Mas imagino que haja uma maneira mais apropriada de realizar o que você está procurando? Não acho que eval () seja algo que você realmente queira usar, a menos que haja uma grande razão para isso. eval ()

goggin13
fonte
3
Sim, eu iria com isso em vez de usar a janela (que tem algumas ressalvas)
ingo
12
Por que uma eval()resposta foi votada para exclusão e esta foi votada?
BoltClock
4
@ogoggin Você deve regex-testar o argumento para garantir que seja um nome válido. Apenas avaliar o argumento sem verificar primeiro é ridiculamente inseguro.
Šime Vidas
16
Esta é a única resposta realista para a pergunta. Só porque envolveu a avaliação "eeeeevil" não a torna menos verdadeira. Javascript não possui variáveis ​​variáveis ​​(como $$ varname em php), então essa é realmente a única resposta. Usar window[varname]tem o efeito colateral de introduzir variáveis ​​globais, que podem não ser desejadas. @ Shaz Acho que você não dá crédito suficiente aos modernos intérpretes JS. Eles são extremamente rápidos e a análise e execução de uma operação simples de atribuição de uma linha não afetará o uso da CPU de ninguém, desde que não esteja sendo feito em um temporizador de 1 ms ou loop apertado.
MooGoo
2
@TheParamagneticCroissant As pessoas apaixonadas por código cuidam. Quem valoriza apenas tempo e dinheiro, não.
Jimbo
41

No que diz respeito a eval vs. soluções variáveis ​​globais ...

Eu acho que há vantagens para cada um, mas essa é realmente uma falsa dicotomia. Se você é paranóico do espaço para nome global, crie um espaço para nome temporário e use a mesma técnica.

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

tempNamespace[myString] = 5;

Com certeza você pode acessar como tempNamespace.myVarProperty (agora 5), ​​evitando usar a janela para armazenamento. (A string também pode ser colocada diretamente entre parênteses)

jm0
fonte
Refatorar um pouco seu código para criar o mesmo var tempNamespace = {["myVarProperty"] inline: "Definitivamente apenas vídeo"};
Tioma
1
Essa é uma solução muito boa - parece que eval () deve ser evitado, a menos que seja absolutamente necessário, uma solução muito elegante aqui.
Skwidbreth 27/02
Começando com a coleção document.body.getElementsByTagName ('*'), é fácil encontrar todos os elementos com um atributo 'id' e criar uma variável para o valor do objeto do elemento de cada um no objeto global 'id'. Em seguida, você pode consultar <div id = container> no JavaScript como 'id.container'. Tão fácil!
David Spector
15
var myString = "echoHello";

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

echoHello();

Diga não ao malvado . Exemplo aqui: https://jsfiddle.net/Shaz/WmA8t/

Shaz
fonte
3
Faça este trabalho no escopo local e removerei o voto negativo.
Tomáš Zato - Restabelece Monica
@ TomášZatofunction aScope() { this[myString] = function() { alert("Hello!"); };};
rrw
@richmondwang thisnão se refere ao escopo local, mas ao objeto ao qual a função está vinculada durante a chamada.
Tomáš Zato - Restabelecer Monica
8

Você pode acessar o objeto de janela como uma matriz associativa e configurá-lo dessa maneira

window["onlyVideo"] = "TEST";
document.write(onlyVideo);
Eric Conner
fonte
8

O método window ['variableName'] ONLY funciona se a variável for definida no escopo global. A resposta correta é "Refatorar". Se você pode fornecer um contexto "Objeto", existe uma possível solução geral, mas existem algumas variáveis ​​que nenhuma função global poderia resolver com base no escopo da variável.

(function(){
    var findMe = 'no way';
})();
Lance Caraccioli
fonte
6

Se você estiver tentando acessar a propriedade de um objeto, precisará começar com o escopo de windowe percorrer cada propriedade do objeto até chegar à que deseja. Supondo que a.b.ctenha sido definido em outro lugar no script, você pode usar o seguinte:

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

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

Isso funcionará para obter a propriedade de qualquer objeto, não importa quão profundo seja.


fonte
Seu exemplo é legal. Observo que, se eu usar namecomo o nome da variável, seu exemplo falhará, mas funcionará com outros nomes de variáveis. Isso pode ter a ver com o objeto Window que já possui uma namevariável. Além disso, a inclusão do .valuemétodo causou falha. A capacidade de interpretar variáveis ​​de objeto profundamente aninhadas é o que estou procurando e seu método indica uma boa direção. Obrigado.
Theo
Sem problemas. A resposta é mais para demonstrar o conceito, em vez de ser um copy / paste resposta (como são a maioria das respostas aqui no SO eu acho)
1
As respostas SO são ainda melhores quando você pode gastar o tempo melhorando-as em vez de corrigi-las. ;-)
Theo
Não funciona:Uncaught TypeError: Cannot read property 'split' of undefined
Roberto14:
5

Você pode fazer assim

var name = "foo";
var value = "Hello foos";
eval("var "+name+" = '"+value+"';");
alert(foo);

Eliyah Sundström
fonte
0

Isso pode ser feito assim

(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());

yunzen
fonte
0

O código a seguir facilita a referência a cada um de seus DIVs e outros elementos HTML em JavaScript. Esse código deve ser incluído logo antes da tag, para que todos os elementos HTML sejam vistos. Deve ser seguido pelo seu 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";
David Spector
fonte
0

deixe-me deixar mais claro

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
Kalidan
fonte
1
Bem-vindo ao Stack Overflow! Embora esse código possa resolver a questão, incluir uma explicação de como e por que isso resolve o problema realmente ajudaria a melhorar a qualidade da sua postagem e provavelmente resultaria em mais votos positivos. Lembre-se de que você está respondendo à pergunta dos leitores no futuro, não apenas à pessoa que está perguntando agora. Por favor edite sua resposta para adicionar explicações e dar uma indicação do que limitações e premissas se aplicam.
Daniil