Преобразовать строку в имя переменной в JavaScript

260

Я искал решения, но не мог найти такую ​​работу.

У меня есть переменная с именем onlyVideo.

"onlyVideo"строка передается в функцию. Я хочу установить переменную onlyVideoвнутри функции как-то. Как я могу это сделать?

(Есть ряд переменных, которые можно вызывать в функции, поэтому мне нужно, чтобы она работала динамически, а не в жестко закодированных ifвыражениях.)

Изменить: вероятно, есть лучший способ сделать то, что вы пытаетесь сделать. Я спросил это в начале моего приключения JavaScript. Посмотрите, как работают объекты JavaScript.

Простое вступление:

// 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
источник
5
Для чего ты это используешь? Вы абсолютно уверены, что вам нужно установить его в нормальную локальную переменную, и объект (хэш) не будет работать?
Догберт
ммм ... я до сих пор не совсем понимаю, почему вы хотите сделать это в мире с массивами. Во всяком случае, некоторые из вашего кода и объяснения очень помогли бы.
Кевин Чавес
я думаю, что нам нужно больше подробностей о том, какова ваша конечная цель
McGrailm

Ответы:

281

Если это глобальная переменная, то window[variableName] или в вашем случае window["onlyVideo"]следует сделать свое дело .

ИНГО
источник
35
Даже если не глобальный, вы можете получить к нему доступ таким образом scope[property]или дажеthis[property]
Войцех Беднарски
7
@WojciechBednarski: не путайте сферу и контекст. thisконтекст, на что он указывает, зависит от того, как вызывается функция. В JS, 50% времени , thisэто , windowесли не включить строгий режим и thisстановится undefinedи выдаст ошибку. Область видимости - это нечто совершенно другое, и это не объект (за исключением глобальной области видимости, которая отражается windowобъектом)
slebetman
3
Не работает в WebWorkers(где selfотносится к глобальной области видимости, так же, как в браузере, где он равен window) и в Node.js, где указана нужная globalпеременная. И это новее работает с локальными областями, такими как тело функции.
Томаш Зато - Восстановить Монику
в любом случае, чтобы определить, constиспользуя этот метод?
toing_toing
165

Javascript имеет eval()функцию для таких случаев:

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

Изменить: Извините, я думаю, что снял вопрос слишком быстро. Это только даст вам переменную, чтобы установить ее вам нужно

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

или если используется строка:

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

Но я думаю, что есть более подходящий способ достичь того, что вы ищете? Я не думаю, что eval () - это то, что вы действительно хотите использовать, если нет веских причин для этого. Eval ()

goggin13
источник
3
Да, я бы пошел с этим, а не с использованием окна (в нем есть некоторые предостережения)
ingo
12
Почему один eval()ответ был отклонен на удаление, а этот был отклонен?
BoltClock
4
@goggin Вы должны regex-проверить аргумент, чтобы убедиться, что это правильное имя. Просто переоценить аргумент, не проверив его сначала, смехотворно небезопасно.
Шиме Видас
16
Это единственный реалистичный ответ на вопрос. То, что в нем участвовал «ээээвил», не делает его менее правдивым. Javascript не имеет переменных переменных (таких как $$ varname в php), так что это действительно единственный ответ. Использование window[varname]имеет побочный эффект от введения глобальных переменных, которые могут быть нежелательны. @Shaz Я не думаю, что вы даете современным переводчикам JS достаточное доверие. Они очень быстрые, и анализ и выполнение простой однострочной операции назначения не приведут к скачкам загрузки ЦП, если это не выполняется в таймере 1 мс или в замкнутом цикле.
MooGoo
2
@TheParamagnCroissant Люди, которые увлечены заботой о коде. Те, кто ценит только время и деньги, не ценят.
Джимбо
41

Насколько eval против глобальных переменных решений ...

Я думаю, что у каждого есть свои преимущества, но это действительно ложная дихотомия. Если вы параноидально относитесь к глобальному пространству имен, просто создайте временное пространство имен и используйте ту же технику.

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

tempNamespace[myString] = 5;

Уверен, что вы можете получить доступ к нему как tempNamespace.myVarProperty (сейчас 5), избегая использования окна для хранения. (Строка также может быть помещена непосредственно в скобки)

jm0
источник
Немного рефакторинг вашего кода, чтобы сделать тот же самый встроенный var tempNamespace = {["myVarProperty"]: "Определенно только видео"};
Tioma
1
Это очень хорошее решение - кажется, что eval () следует избегать, если в этом нет абсолютно необходимой, очень элегантный обходной путь.
skwidbreth
Начиная с коллекции document.body.getElementsByTagName ('*'), легко найти все элементы, имеющие атрибут 'id', и создать переменную для значения объекта element каждого из них в глобальном объекте 'id'. Затем вы можете ссылаться на <div id = container> в JavaScript как «id.container». Так легко!
Дэвид Спектор
15
var myString = "echoHello";

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

echoHello();

Скажи нет злому эвалу. Пример здесь: https://jsfiddle.net/Shaz/WmA8t/

Shaz
источник
3
Сделайте эту работу на местном уровне, и я уберу понижение.
Томаш Зато - Восстановить Монику
@ TomášZatofunction aScope() { this[myString] = function() { alert("Hello!"); };};
rrw
@richmondwang this- это не ссылка на локальную область видимости, а на объект, с которым связана функция во время вызова.
Томаш Зато - Восстановить Монику
8

Вы можете получить доступ к объекту окна как ассоциативный массив и установить его таким образом

window["onlyVideo"] = "TEST";
document.write(onlyVideo);
Эрик Коннер
источник
8

Метод window ['variableName'] работает ТОЛЬКО, если переменная определена в глобальной области видимости. Правильный ответ - «Рефакторинг». Если вы можете предоставить контекст «Объект», то возможно общее решение, но есть некоторые переменные, которые ни одна глобальная функция не может разрешить в зависимости от области действия переменной.

(function(){
    var findMe = 'no way';
})();
Ланс Караччиоли
источник
6

Если вы пытаетесь получить доступ к свойству объекта, вы должны начать с области действия windowи проходить через каждое свойство объекта, пока не дойдете до того, которое вам нужно. Предполагая, что a.b.cэто было определено где-то еще в скрипте, вы можете использовать следующее:

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

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

Это будет работать для получения свойства любого объекта, независимо от его глубины.


источник
Ваш пример классный. Я отмечаю, что если я использую в nameкачестве имени переменной, ваш пример не удастся, но он работает с другими именами переменных. Это может иметь отношение к объекту Window, уже имеющему nameпеременную. Также в том числе .valueметод вызвал сбой. Возможность интерпретировать глубоко вложенные переменные объекта - это то, что я ищу, и ваш метод указывает правильное направление. Спасибо.
Тео
Нет проблем. Ответ скорее для того, чтобы продемонстрировать концепцию, чем для того, чтобы быть ответом на копирование / вставку (как и большинство ответов здесь на SO, я думаю)
1
Так что ответы даже лучше, когда вы можете потратить время на их улучшение, а не на исправление. ;-)
Тео
Не работает:Uncaught TypeError: Cannot read property 'split' of undefined
Roberto14
5

Вы можете сделать это

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

Элия ​​Сундстрем
источник
0

Это можно сделать так

(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
источник
0

Следующий код позволяет легко ссылаться на каждый из ваших DIV и других элементов HTML в JavaScript. Этот код должен быть включен непосредственно перед тегом, чтобы все элементы HTML были видны. За ним должен следовать ваш код 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";
Дэвид Спектор
источник
-1

позвольте мне сделать это более ясным

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
источник
1
Добро пожаловать в стек переполнения! Хотя этот код может решить вопрос, в том числе объяснение того, как и почему это решает проблему, действительно поможет улучшить качество вашего сообщения и, вероятно, получит больше голосов "за". Помните, что вы отвечаете на вопрос для читателей в будущем, а не только для того, кто спрашивает сейчас. Пожалуйста, измените свой ответ, чтобы добавить объяснения и указать, какие ограничения и предположения применяются.
Даниил