Попытка избежать eval получения элемента массива из оконного объекта - PullRequest
0 голосов
/ 02 декабря 2011

У меня есть функция, которая хочет получить доступ к глобальной переменной, имя которой появляется в виде строкового аргумента.Вот как это выглядит сейчас, используя eval:

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

Я подумал, что просто использую синтаксис окна [] и получу это:

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

Если я создам переменную иназовите это так, он пишет ABC, как и ожидалось:

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

Если переменная, к которой я хочу получить доступ, является элементом массива, он не работает:

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

Очевидно,это фактически выполняет окно [def [0]], которое справедливо дает неопределенное значение (потому что нет переменной с именем DEF).На самом деле я хочу, чтобы он выполнял window ["def"] [0].

Единственный способ, которым я знаю, чтобы добиться этого, - это разделить параметр whichone с "[" в качестверазделитель, а затем используйте split [0] в качестве индекса окна и parseInt в split [1], чтобы получить индекс, например:

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] );
  }
}

Я пропускаю что-то очевидное?Я предпочел бы сохранить Eval, чем делать все это.

Ответы [ 4 ]

1 голос
/ 02 декабря 2011

Если вам не нравится использование eval в вашем коде, вы всегда можете сделать это:

function echoVar(whichone) {
  document.write(Function("return " + whichone)());
}
0 голосов
/ 02 декабря 2011

Было бы проще потерять скобки и вызвать пункт с точечной нотацией

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
*/
0 голосов
/ 02 декабря 2011

Дело в том, что у вас есть фрагмент 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/

0 голосов
/ 02 декабря 2011

Если это не неудачный эксперимент, вы никогда не должны писать код Javascript, который выглядит следующим образом. Это ужасно; Вы должны переосмыслить свой дизайн. Я знаю, что это не то, что вы ищете, но это правильный ответ.

...