在JavaScript中使用动态变量名称

Fin*_*arr 320 javascript dynamic-variables

在PHP中你可以做这样惊人/可怕的事情:

$a = 1;
$b = 2;
$c = 3;
$name = 'a';
echo $$name;
// prints 1
Run Code Online (Sandbox Code Playgroud)

有没有办法用Javascript做这样的事情?

例如,如果我有一个var name = 'the name of the variable';可以获得名称变量的引用name

jAn*_*ndy 335

由于ECMA-/Javascript都是关于ObjectsContexts(它们也是Object的一些),每个变量都存储在一个这样的变量中(或者在函数,激活对象的情况下).

所以如果你创建这样的变量:

var a = 1,
    b = 2,
    c = 3;
Run Code Online (Sandbox Code Playgroud)

全局范围(= NO函数上下文)中,您隐式将这些变量写入Global对象(= window在浏览器中).

可以使用"点"或"括号"表示法访问这些:

var name = window.a;
Run Code Online (Sandbox Code Playgroud)

要么

var name = window['a'];
Run Code Online (Sandbox Code Playgroud)

这仅适用于在这种特定情况下的全局对象,因为变量对象中的全局对象window对象本身.在函数的上下文中,您无法直接访问激活对象.例如:

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

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

new foobar();
Run Code Online (Sandbox Code Playgroud)

new创建自定义对象(上下文)的新实例.没有new函数的范围也会global(= window).这个例子将提醒undefined1分别.如果我们将替换this.a = 1; this.b = 2为:

var a = 1,
    b = 2;
Run Code Online (Sandbox Code Playgroud)

两个警报输出都是未定义的.在这种情况下,变量ab会被存储在从启动对象foobar,这是我们不能访问(当然,我们可以直接调用访问那些ab).

  • 但是如果我的动态变量在函数中是局部的呢?例如:function boink(){var a = 1; //这不起作用var dynamic = this ['a']; //这也不会工作var dynamic = ['a']; } (4认同)

eri*_*ckb 145

eval 是一种选择.

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

document.write(eval(name)); // 1
Run Code Online (Sandbox Code Playgroud)

  • @EasyBB - 如果你要说永远不要使用某些东西,我没有帮助解释原因.我有一种情况,我无法想到任何其他方式来完成我正在做的事情而不是eval() (42认同)
  • 不,它不应该因为eval是邪恶的.永远不要使用eval! (12认同)
  • Eval会对最终用户的攻击造成风险,我们在技术上并不会因为丢失案件而被误解和误用.我已经看到了php响应,其中包含文字变量,然后使用eval来运行它.虽然在这种情况下不应该使用它,因为有更好的方法.由于总体上有更好的方法,所以不应该使用这个问题,因为我们很多人都知道这一点. (3认同)
  • 通过https://javascriptweblog.wordpress.com/2010/04/19/how-evil-is-eval/ ---"让我们考虑最常使用eval的参数:1)它需要编译,因此很慢2)如果恶意脚本进入eval参数会怎么样?3)它看起来很难看4)它继承了执行上下文和它调用的作用域的这种绑定" (2认同)

Joh*_*hnP 75

您可以使用window对象来获取它.

window['myVar']
Run Code Online (Sandbox Code Playgroud)

window 引用了您正在使用的所有全局变量和全局函数.

  • 不用说,这个比eval()更安全. (26认同)

Ter*_*Lin 39

只是不知道什么是错误的答案获得如此多的选票.这很容易回答,但你让它变得复杂.

// 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);
Run Code Online (Sandbox Code Playgroud)

  • "在函数中我们使用`this`" - 如果你想以这种方式访问​​_global_变量,最好是显式并使用`window`对象,而不是`this`."这个"含糊不清. (11认同)
  • 但是**在函数内部**,如果您在另一个变量中有它的名称,则不能使用“this”或其他任何内容来访问示例中的变量“type”:“function test(vname) { var type = '文章'; this[vname] = '其他东西'; 警报(类型);}; test('type')` 将显示“article”,而不是“其他内容”。这就是“复杂答案”所解释的。 (2认同)

ami*_*chd 28

a = 'varname';
str = a+' = '+'123';
eval(str)
alert(varname);
Run Code Online (Sandbox Code Playgroud)

试试这个...


Azo*_*ium 27

这是一个例子:

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
Run Code Online (Sandbox Code Playgroud)

另一个例子 :

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

alert(coco); // display : riko
Run Code Online (Sandbox Code Playgroud)

因此,myVariable的值" coco " 变为可变coco.

因为全局范围中的所有变量都是Window对象的属性.


Dav*_*omb 12

在Javascript中,您可以使用所有属性都是键值对的事实.jAndy已经提到了这一点,但我不认为他的答案显示了如何利用它.

通常,您不是要创建一个变量来保存变量名,而是尝试生成变量名然后再使用它们.PHP用$$var符号表示,但Javascript不需要,因为属性键可以与数组键互换.

var id = "abc";
var mine = {};
mine[id] = 123;
console.log(mine.abc);
Run Code Online (Sandbox Code Playgroud)

给出123.通常你想构造变量,这就是为什么存在间接,所以你也可以反过来做.

var mine = {};
mine.abc = 123;
console.log(mine["a"+"bc"]);
Run Code Online (Sandbox Code Playgroud)


per*_*mon 7

2019年

TL; 博士

  • eval 运算符可以在它调用的上下文中运行字符串表达式并从该上下文返回变量;
  • literal object理论上可以通过 write: 做到这一点{[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
Run Code Online (Sandbox Code Playgroud)

请注意,我总是明确地编写表达式eval将运行。避免代码中出现不必要的意外。eval很强大 但我相信你已经知道了

顺便说一句,如果它是合法的,我们可以literal object用来捕获变量名称和值,但我们不能组合计算属性名称和属性值速记,遗憾的是,这是无效的

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

    var capture = {[varName]}

}

example('var1') //trow 'Uncaught SyntaxError: Unexpected token }`
Run Code Online (Sandbox Code Playgroud)


Bre*_*ata 6

如果你不想使用像 window 或 global(节点)这样的全局对象,你可以尝试这样的事情:

var obj = {};
obj['whatever'] = 'There\'s no need to store even more stuff in a global object.';

console.log(obj['whatever']);
Run Code Online (Sandbox Code Playgroud)


小智 6

我需要动态绘制多个 FormData 并且对象方式运行良好

var forms = {}
Run Code Online (Sandbox Code Playgroud)

然后在我的循环中我需要创建我使用的表单数据

forms["formdata"+counter]=new FormData();
forms["formdata"+counter].append(var_name, var_value);
Run Code Online (Sandbox Code Playgroud)