1

I'm trying to get the type of of a string evaluated with eval() with no success.

The variable is a string stored in an array with the name of a possible object which I want to know if is defined.

Can someone give a hand please?

The troubling line is if ( typeof eval( x[i][0] ) !== 'undefined' ) and this is my code:

    var infoslider = [
    ["revapi5", "el-masnou", "sant-andreu-de-llavaneres"],
    ["revapi3", "sant-andreu-de-llavaneres", "cardedeu"],
    ["revapi10", "cardedeu", "eudald-carbonell"],
    ["revapi9", "arenys-de-mar", "canet-de-mar"]
];
var x = infoslider;
for (var i = 0; i < x.length; i++) {
    if ( typeof eval( x[i][0] ) !== 'undefined' ) {
        vesa(x[i][0], x[i][2]);
    }
}

I get "ReferenceError: revapi5 is not defined"

Jamiec
  • 133,658
  • 13
  • 134
  • 193
Xavier Caliz
  • 143
  • 2
  • 9
  • 2
    What makes you think you need or want `eval` there? – T.J. Crowder Apr 17 '15 at 13:19
  • *"The variable is a string stored in an array with the name of a possible object which I want to know if is defined."* Not quite following. Are you saying you may or may not have a variable called (for instance) `revapi5`? – T.J. Crowder Apr 17 '15 at 13:21
  • [I've answered what you actually asked](http://stackoverflow.com/a/29700479/157247), I think, but this seems like the "X/Y problem": You need to solve X, and you think Y will help you do that, but you're having trouble doing Y and asked how to do Y -- but if we knew what X was, we could probably suggest a better solution than Y. :-) – T.J. Crowder Apr 17 '15 at 13:28
  • I want to know if revapi5 is actually an defined object. In fact I want to simplify a code that checks if this object is defined. The initial code is: if (typeof revapi3 !== 'undefined') { vesa(revapi3, 'el-masnou') // Masnou } else if (typeof revapi5 !== 'undefined') { vesa(revapi5, 'arenys-de-mar') // Entrevista Carbonell } else if (typeof revapi6 !== 'undefined') { vesa(revapi6, 'arenys-de-mar') // Cementiri Arenys de Mar }// end if typeof – Xavier Caliz Apr 17 '15 at 13:33
  • My answer tells you how to do that, but again, it's the X/Y thing: ***Why*** do you want to know if `revapi5` is a declared variable? Where does it come from? Is it a global? A local? – T.J. Crowder Apr 17 '15 at 13:36

2 Answers2

3

Don't use eval, try this:

typeof window[ x[i][0] ] !== 'undefined'

Taken from this answer

Update:

If your variables are not stored globally, you can swap window for whatever object they're stored in (assuming it's in scope)... if it's the same object then this should work.

Also @vol7ron made a better suggestion of using .hasOwnPropery rather than checking for undefined.

Community
  • 1
  • 1
DanielM
  • 6,380
  • 2
  • 38
  • 57
  • That will only work if these variables are globals. Globals are, of course, best avoided, so... – T.J. Crowder Apr 17 '15 at 13:26
  • 1
    And if you're going to use globals, you might as well just do `if ( window.hasOwnProperty(x[i][0]) ) { ... }` – vol7ron Apr 17 '15 at 13:29
  • 1
    That's more of a preference thing for readability. `hasOwnProperty` suggests looking for the existence. However, it's important to note that `typeof` would be much more efficient; so if every microsecond of performance is an issue, or if this is going to be put in a loop, that could matter. I haven't seen the need for this level of optimization since needing to write a super resource intensive application to be able to run on early version of smartphones. So it's better to be more readable for maintainability. – vol7ron Apr 17 '15 at 13:53
  • 1
    Yeah, I guess saying "better" is subjective, but for those of us who hate programatically dealing with strings (which actually is what this question is about) as it hides functionality, `.hasOwnProperty` is preferable. IDE's will additionally help prevent you getting a typo in that too. :p – DanielM Apr 17 '15 at 13:57
2

The variable is a string stored in an array with the name of a possible object which I want to know if is defined.

If you mean that there may or may not be a variable named revapi5 declared and it will have a value other than undefined if it is declared, and you want to know whether it is, you could move the typeof into the string you're eval'ing:

if ( eval( "typeof " + x[i][0] ) !== 'undefined' ) {

But, there's almost certainly a better way to solve whatever the problem is that you're trying to solve by doing that.

Example of the above:

var revapi5 = {}; // We do have 5, but we don't have the others
var infoslider = [
  ["revapi5", "el-masnou", "sant-andreu-de-llavaneres"],
  ["revapi3", "sant-andreu-de-llavaneres", "cardedeu"],
  ["revapi10", "cardedeu", "eudald-carbonell"],
  ["revapi9", "arenys-de-mar", "canet-de-mar"]
];
var x = infoslider;
for (var i = 0; i < x.length; i++) {
  if (eval("typeof " + x[i][0]) !== 'undefined') {
    snippet.log(x[i][0] + " is declared and has a value other than undefined");
  } else {
    snippet.log(x[i][0] + " is either undeclared, or has the value undefined");
  }
}
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • @Siguza: Thanks -- meant to *move* `typeof` rather than adding a second one, just fixed it when adding a live example. – T.J. Crowder Apr 17 '15 at 13:25
  • @T.J Crowder It works! That's the final code: var infoslider = [ ["revapi5", "el-masnou", "sant-andreu-de-llavaneres"], ["revapi3", "sant-andreu-de-llavaneres", "cardedeu"], ["revapi10", "cardedeu", "eudald-carbonell"], ["revapi9", "arenys-de-mar", "canet-de-mar"] ]; var x = infoslider; var z = ""; for (var i = 0; i < x.length; i++) { if ( eval ( "typeof " + x[i][0] ) !== 'undefined' ) { vesa(eval(x[i][0]), x[i][2]); } } DanielM your code also worked but I prefer to avoid globals. Thanks! – Xavier Caliz Apr 17 '15 at 14:10