【问题标题】:How to find JavaScript variable by its name如何通过名称查找 JavaScript 变量
【发布时间】:2009-04-07 09:43:47
【问题描述】:

有没有办法通过名称在页面上找到 JavaScript 变量(将其作为对象获取)?变量名可作为字符串常量使用。

【问题讨论】:

标签: javascript


【解决方案1】:
<script>
var a ="test";
alert(a);
alert(window["a"]);
alert(eval("a"));
</script>

【讨论】:

  • 请不要使用eval
  • 非全局变量呢?除了eval,还有其他选择吗?
  • @mxro:在那种情况下,你会想使用object property
【解决方案2】:

所有 JS 对象(哪些变量是)在其范围内都可以作为其父对象的命名属性使用。在不存在显式父对象的情况下,它隐含为 window 对象。

即:

var x = 'abc';
alert(window['x']); //displays 'abc'

对于复杂的对象:

var x = {y:'abc'};
alert(x['y']); //displays 'abc'

这可以链接:

var x = {y:'abc'};
alert(window['x']['y']); //displays 'abc'

【讨论】:

  • 这仅适用于全局范围的变量 - 如果范围是函数级,则没有允许访问词法环境的对象
  • 当然可以,但没有什么能帮到你。这假设您可以将 var 表示为点符号结构。
  • 如果您需要在函数中执行此操作,唯一的解决方案是将您的 vars 放入反对中,并访问对象的键,例如:stackoverflow.com/questions/4109297/…
  • @Juan - 但这不是功能级别的范围。
  • 这就是我评论的重点。没有 eval,你无法对本地函数执行此操作。
【解决方案3】:

如果您想要一个在全局上下文中声明的变量,则将其附加到窗口对象。例如:窗口[“变量名”]。所有变量都是其范围内的哈希表值。

如果您必须使用点分表示法,那么您将需要遵循 kennebec 的建议,在对象层次结构中导航。 eval() 也可以工作,但它比可能需要的操作更昂贵。

【讨论】:

    【解决方案4】:

    如果它是一个全局变量,你可以在全局对象上按名称查找它,因为全局变量是全局对象的属性。在浏览器上,有一个全局变量引用名为 window 的全局对象,所以:

    var name = "foo";
    window.foo = 42;
    alert(Number(window[name])); // 42
    

    但是全局变量是个坏事(tm)

    要在没有全局变量的情况下执行此操作,请使用您自己的对象:

    var name = "foo";
    var obj = {};
    obj.foo = 42;
    alert(Number(obj[name])); // 42
    

    上述两种方法都有效,因为在 JavaScript 中,您可以使用点符号和文字 (obj.foo) 或括号符号和字符串 (obj["foo"]) 来引用对象属性,在后一种情况下,字符串可以是任何表达式的结果,包括变量查找。

    【讨论】:

    • 如果obj 是要访问的变量(而不是obj.foo),那eval 会是唯一的选择吗?
    • @mxro:如果obj 是一个全局变量,您可以使用window["obj"]。如果不是,那么您必须使用eval。但我不会,我会更改我的代码以将 obj 放入容器中,这样我就可以以正常方式查找它。
    • 是的,听起来不错。我想我最初在eval 语句中创建了一个变量,然后我只能通过第二个eval 检索它 - 但随后更改了在第一个eval 之前创建容器变量的代码;无需第二个eval
    • @mxro:如果您在eval 中创建变量,您应该可以正常访问它:eval("var x = 42;"); console.log(x); 在控制台中显示 42。 (但几乎没有任何理由使用eval。)
    • 哇,谢谢,这也很有用。但你说得对,不是很干净,我同意!
    【解决方案5】:

    如果您的字符串引用了全局的“深度”属性,例如“Yankee.console.format”,您可以单步执行引用:

    String.prototype.deref= function(){
        // remove leading and trailing quotes and spaces
        var obj= this.replace(/(^[' "]+|[" ']+$)/g,'');
    
        var M= obj.match(/(^[\w\$]+(\.[\w\$]+)*)/);
        if(M){
            M= M[1].split('.');
            obj= window[M.shift()];
            while(obj && M.length) obj= obj[M.shift()];
        }   
        return obj || this;
    }
    

    【讨论】:

      【解决方案6】:
      var getVar = function (obj) {
          for(var key in this) {
              if(obj === this[key]) return key;
          }
      };
      
      foo = 'foo';
      
      console.log( getVar(foo) ); // => 'foo'
      

      https://stackoverflow.com/a/17432007/1250044

      【讨论】:

      • double foo 帮助关注
      • 这将仅返回窗口上具有给定值的第一个变量的值。我看不出这样做有什么意义,因为它不会告诉你任何你不知道的事情。
      【解决方案7】:

      你可以使用 eval()

      【讨论】:

      • 从不永远在不需要的地方使用 eval
      • 投票。简单的问题值得简单的回答。如果我出于某种原因需要通过变量名查看变量的内容,我会选择 eval()。
      • A)。 window[foo] 有什么不简单的?乙)。那么速度和安全性不关心你吗? eval 有毒,严重
      • 我不想让任何人认为这是一场比赛——老实说,我不会对此投反对票——我接受 eval 确实在技术上解决了问题,但无论如何 eval 是核选项。最好不用它。
      • @Peter,这不是一场比赛,但大多数精通 JS 开发人员会避免像瘟疫一样避免 evalwith。对您的解决方案表示不喜欢应该是可以的。我永远不会发布 eval 作为解决方案,除非没有其他解决方案,或者它太麻烦了
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多