试图避免eval从window对象获取数组元素

时间:2011-12-02 00:44:17

标签: javascript eval

我有一个想要访问全局变量的函数,其名称作为字符串参数到达。现在看来,使用eval:

function echoVar(whichone){
  document.write(eval(whichone));
}

我以为我只是使用window []语法并拥有:

function echoVar(whichone) {
  document.write(window[whichone]);
}

如果我创建一个var并像这样调用它,它会按预期编写ABC:

var abc = "ABC";
echoVar("abc");

如果我想要访问的var是一个数组元素,它不起作用:

var def = ["DEF"];
echoVar("def[0]");  //fails with undefined

显然,实际上正在执行窗口[def [0]],它正确地给出了undefined(因为没有名为DEF的变量)。我实际想要发生的是它执行window [“def”] [0]。

我知道实现这一目标的唯一方法是对whereone参数进行拆分,以“[”作为分隔符,然后使用split [0]作为窗口索引,并使用split [1]上的parseInt获取索引,像这样:

function echoVar(whichone){
  if(whichone.indexOf("[")==-1){
    document.write(window[whichone]);
  }
  else{
    var s = whichone.split("[");
    var nam = s[0];
    var idx = parseInt(s[1]);
    document.write( window[nam][idx] );
  }
}

我忽略了一些明显的东西吗?我宁愿保持评估而不是做所有这些。

4 个答案:

答案 0 :(得分:1)

如果您不喜欢在代码中使用eval,则可以随时执行此操作:

function echoVar(whichone) {
  document.write(Function("return " + whichone)());
}

答案 1 :(得分:0)

除非这是一些生病的实验,否则你永远不应该编写看起来像这样的Javascript代码。这很糟糕;你需要重新思考你的设计。我知道这不是你想要的,但这是正确的答案。

答案 2 :(得分:0)

事实上,你在字符串中有一段javscript表达式,所以你要么自己解析它,要么使用eval为你解析它,除非你改变它的传递方式:

function echoVar(a,b) {
    var x = window[a];
    if (b) {
        x = x[b];
    }
    document.write(x);
}

然后你可以这样传递它:

var def = ["DEF"];
echoVar("def", 0);    // def[0]

如果需要,您甚至可以支持多个维度。

function echoVar(a) {
    var x = window[a];
    for (var i = 1; i < arguments.length; i++) {
        x = x[arguments[i]];
    }
    document.write(x);
}

var def = {myObject: {length: 3}}
echoVar("def", "myObject", "length");    // def["myObject"]["length"] or def.myObject.length

您可以在此处查看:http://jsfiddle.net/jfriend00/dANwq/

答案 3 :(得分:0)

丢失括号并用点符号

调用项目会更简单
function reval(s, O){
    s= String(s);
    O= O || window;
    var N= s.split(".");
    while(O && N.length) O= O[N.shift()];
    return O || s;
}

window.def= ['definition'];
alert(reval('def.0'))

/*  returned value: (String)
definition
*/