【问题标题】:Convert string to variable name in JavaScript在 JavaScript 中将字符串转换为变量名
【发布时间】:2011-08-02 14:22:41
【问题描述】:

我一直在寻找解决方案,但找不到任何可行的方法。

我有一个名为 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;

【问题讨论】:

  • 你用这个做什么?您确定需要将其设置为普通的局部变量,而对象(哈希)不起作用吗?
  • 嗯...我仍然不太明白为什么要在一个有数组的世界中这样做。无论如何,你的一些代码和解释会有很大帮助。
  • 我认为我们需要更多关于您的最终目标的详细信息

标签: javascript variables


【解决方案1】:

如果是全局变量,那么window[variableName] 或者在您的情况下,window["onlyVideo"] 应该可以解决问题。

【讨论】:

  • 即使不是全局的,您也可以通过scope[property] 甚至this[property] 访问它
  • @WojciechBednarski:不要混淆范围和上下文。 this 是上下文,它指向的内容取决于函数的调用方式。在 JS 中,50% 的时间thiswindow,除非你启用严格模式并且this 变成undefined 并且会抛出错误。范围是完全不同的东西,它不是一个对象(除了由window 对象镜像的全局范围)
  • WebWorkers 中不起作用(其中self 指的是全局范围,就像在浏览器中一样,它等于window)和Node.js,其中global是你想要的变量。而且它较新的适用于局部范围,例如函数体。
  • 有没有用这种方法定义const
  • 如果变量是使用 let 和 const 创建的呢?它不会成为全局范围的一部分。
【解决方案2】:

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

【讨论】:

  • 是的,我会选择这个而不是使用窗口(它有一些警告)
  • 为什么一个eval() 回答被否决,而这个被赞成?
  • @goggin 您应该对参数进行正则表达式测试以确保它是有效名称。仅仅评估参数而不首先检查它是非常不安全的。
  • 这是对这个问题的唯一现实答案。仅仅因为它涉及“eeeeevil”评估并没有使它变得不那么真实。 Javascript 没有可变变量(例如 php 中的 $$varname),所以这确实是唯一的答案。使用window[varname] 具有引入全局变量的副作用,这可能是不需要的。 @Shaz 我认为您没有给予现代 JS 解释器足够的信任。它们非常快,只要不是在 1ms 计时器或紧密循环中完成,解析和执行简单的单行赋值操作就不会增加任何人的 CPU 使用率。
  • @TheParamagneticCroissant 对代码维护充满热情的人。只看重时间和金钱的人不看重。
【解决方案3】:

就 eval 与全局变量解决方案而言...

我认为每个人都有优点,但这确实是一种错误的二分法。 如果您对全局命名空间有偏执,只需创建一个临时命名空间并使用相同的技术。

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

tempNamespace[myString] = 5;

很确定您可以使用 tempNamespace.myVarProperty(现在为 5)访问,避免使用窗口进行存储。 (字符串也可以直接放在括号中)

【讨论】:

  • 稍微重构您的代码以制作相同的内联 var tempNamespace = {["myVarProperty"]: "Definitely only video"};
  • 这是一个非常好的解决方案 - 除非绝对必要,否则似乎应该避免使用 eval(),这里非常优雅的解决方法。
  • 从集合 document.body.getElementsByTagName('*') 开始,很容易找到所有具有 'id' 属性的元素,并为每个元素的元素对象值创建一个变量全局对象'id'。然后您可以将 JavaScript 中的
    称为“id.container”。这么简单!
【解决方案4】:
var myString = "echoHello";

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

echoHello();

邪恶评价说不。此处示例:https://jsfiddle.net/Shaz/WmA8t/

【讨论】:

  • 在本地范围内进行这项工作,我将删除反对票。
  • @TomášZato function aScope() { this[myString] = function() { alert("Hello!"); };};
  • @richmondwang this 不是对本地范围的引用,而是对函数在调用期间绑定到的对象的引用。
【解决方案5】:

您可以将窗口对象作为关联数组访问并以这种方式进行设置

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

【讨论】:

    【解决方案6】:

    你可以这样做

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

    【讨论】:

      【解决方案7】:

      window['variableName'] 方法仅适用于在全局范围内定义变量的情况。正确答案是“重构”。如果您可以提供“对象”上下文,则存在可能的通用解决方案,但有一些变量没有全局函数可以根据变量的范围解析。

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

      【讨论】:

        【解决方案8】:

        如果您尝试访问对象的属性,则必须从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 作为变量名,您的示例将失败,但它适用于其他变量名。这可能与已经具有name 变量的Window 对象有关。此外,包括.value 方法导致失败。我正在寻找解释深度嵌套对象变量的能力,而您的方法表明了一个好的方向。谢谢。
        • 没问题。答案更多是为了展示这个概念,而不是复制/粘贴答案(我认为这里的大多数答案都是如此)
        • 当您可以花时间改进而不是修复它们时,SO 响应会更好。 ;-)
        • 不起作用:Uncaught TypeError: Cannot read property 'split' of undefined
        【解决方案9】:

        可以这样实现

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

        【讨论】:

          【解决方案10】:

          以下代码可以轻松地在 JavaScript 中引用每个 DIV 和其他 HTML 元素。这段代码应该包含在标签之前,这样所有的 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";
          

          【讨论】:

            【解决方案11】:

            让我说得更清楚

            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
            

            【讨论】:

            • 欢迎来到 Stack Overflow!虽然这段代码可以解决问题,including an explanation 解决问题的方式和原因确实有助于提高帖子的质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的回答添加解释并说明适用的限制和假设。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-08-27
            • 2010-12-04
            • 1970-01-01
            • 2011-03-24
            相关资源
            最近更新 更多