Dee2000
Dee2000

Reputation: 1641

Trying to avoid eval getting array element from window object

I've got a function that wants to access a global variable, the name of which arrives as a string argument. This is how it looks now, using eval:

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

I thought I'd just use the window[] syntax and have this:

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

If I create a var and call it like this, it doc writes ABC as expected:

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

If the var I want to access is an array element though, it doesn't work:

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

Obviously that's actually executing window[def[0]] which rightly gives undefined (because there's no variable called DEF). What I actually want to happen is that it executes window["def"][0].

The only way I know to achieve this, is to do a split on the whichone parameter with "[" as the delimiter and then use the split [0] as the window index and a parseInt on split [1] to get the index, like this:

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

Am I overlooking something obvious? I'd rather keep the eval than have to do all that.

Upvotes: 0

Views: 439

Answers (4)

kennebec
kennebec

Reputation: 104780

It would be simpler to lose the brackets and call the item with dot notation

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
*/

Upvotes: 0

ft1
ft1

Reputation: 26

If you dislike using eval in your code, you can always do this:

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

Upvotes: 1

jfriend00
jfriend00

Reputation: 707466

The fact is you've got a piece of a javscript expression in a string so you either have to parse it yourself or use eval to parse it for you unless you change the way it's passed like this:

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

And, then you can pass it differently like this:

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

You could even make this support multiple dimensions if you needed to.

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

You can see it work here: http://jsfiddle.net/jfriend00/dANwq/

Upvotes: 0

Travis Webb
Travis Webb

Reputation: 15018

Unless this is some sick experiment, you should never be writing Javascript code that looks like this. This is terrible; you need to re-think your design. I know this isn't what you're looking for, but it's the right answer.

Upvotes: 0

Related Questions