Используйте имена динамических переменных в JavaScript - PullRequest
309 голосов
/ 25 февраля 2011

В PHP вы можете делать удивительные / ужасные вещи, как это:

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

Есть ли способ сделать что-то подобное с Javascript?

например. если у меня есть var name = 'the name of the variable';, могу ли я получить ссылку на переменную с именем name?

Ответы [ 15 ]

320 голосов
/ 25 февраля 2011

Поскольку ECMA- / Javascript все о Objects и Contexts (которые также являются чем-то вроде Object), каждая переменная хранится в так называемой Variable- (или в случаеФункция, Объект активации ).

Итак, если вы создаете переменные, подобные этой:

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

В Глобальной области действия (= НЕТ контекста функции), вы неявно записываете эти переменные в Глобальный объект (= window в браузере).

К ним можно получить доступ, используя обозначение «точка» или «скобка»:

var name = window.a;

или

var name = window['a'];

Это работает только для глобального объекта в данном конкретном случае, потому что Переменный объект из Глобальный объект это сам объект window.В контексте функции у вас нет прямого доступа к объекту активации .Например:

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

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

new foobar();

new создает новый экземпляр самоопределяемого объекта (контекста).Без new область действия функции также будет global (= окно).Этот пример будет предупреждать undefined и 1 соответственно.Если бы мы заменили this.a = 1; this.b = 2 на:

var a = 1,
    b = 2;

Оба выхода оповещения были бы неопределенными.В этом сценарии переменные a и b будут храниться в объекте активации из foobar, к которому мы не можем получить доступ (конечно, мы можем получить к ним прямой доступ, вызвав a и b).

142 голосов
/ 25 февраля 2011

eval является одним из вариантов.

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

document.write(eval(name)); // 1
73 голосов
/ 25 февраля 2011

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

window['myVar']

window содержит ссылку на все глобальные переменные и глобальные функции, которые вы используете.

35 голосов
/ 21 января 2015

Просто не знаю, какой плохой ответ набирает столько голосов.Это довольно простой ответ, но вы делаете его сложным.

// 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);
28 голосов
/ 25 февраля 2011
a = 'varname';
str = a+' = '+'123';
eval(str)
alert(varname);

Попробуйте это ...

23 голосов
/ 24 января 2015

Это пример:

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

Другой пример:

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

alert(coco); // display : riko

Итак, значение " кокос " myVariable становится переменной кокос .

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

12 голосов
/ 27 ноября 2014

В Javascript вы можете использовать тот факт, что все свойства являются парами ключ-значение.jAndy уже упоминал об этом, но я не думаю, что его ответ показывает, как его можно использовать.

Обычно вы не пытаетесь создать переменную для хранения имени переменной, но пытаетесь сгенерировать имена переменных и затем использовать их,PHP делает это с $$var нотацией, но Javascript не нужен, потому что ключи свойств взаимозаменяемы с ключами массива.

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

дает 123. Обычно вы хотите создать переменную, поэтому существует косвенное обращениетак что вы можете сделать это и наоборот.

var mine = {};
mine.abc = 123;
console.log(mine["a"+"bc"]);
4 голосов
/ 30 января 2015

Если вы не хотите использовать глобальный объект, такой как окно или глобальный (узел), вы можете попробовать что-то вроде этого:

2 голосов
/ 04 января 2019

2019

TL; DR

  • eval оператор может запустить строковое выражение в вызываемом контексте и вернуть переменные из этого контекста;
  • literal object теоретически может сделать это записью: {[varName]}, но он заблокирован по определению.

Итак, я сталкиваюсь с этим вопросом, и все здесь просто играют, не предлагая реального решения.но у @Axel Heider хороший подход.

Решение - eval.почти самый забытый оператор.(наиболее вероятно, что оператор with())

eval может динамически запускать выражение в вызываемом им контексте.и вернуть результат этого выражения.мы можем использовать это для динамического возврата значения переменной в контексте функции.

пример:

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

Обратите внимание, что я всегда пишу явно, выражение eval будет выполняться.Чтобы избежать ненужных сюрпризов в коде.eval очень сильный Но я уверен, что вы уже знаете, что

Кстати, если бы это было законно, мы могли бы использовать literal object для захвата имени и значения переменной, но мы не можем объединитьК сожалению, сокращенные имена и значения вычисляемых свойств недействительны

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

    var capture = {[varName]}

}

example('var1') //trow 'Uncaught SyntaxError: Unexpected token }`
2 голосов
/ 18 сентября 2017

Мне нужно было нарисовать несколько FormData на лету, и способ объекта работал хорошо

var forms = {}

Затем в моих циклах мне нужно было создать данные формы, которые я использовал

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