{"id":486,"date":"2022-08-30T15:02:09","date_gmt":"2022-08-30T15:02:09","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2013\/11\/09\/trying-to-avoid-eval-getting-array-element-from-window-object-collection-of-common-programming-errors\/"},"modified":"2022-08-30T15:02:09","modified_gmt":"2022-08-30T15:02:09","slug":"trying-to-avoid-eval-getting-array-element-from-window-object-collection-of-common-programming-errors","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2022\/08\/30\/trying-to-avoid-eval-getting-array-element-from-window-object-collection-of-common-programming-errors\/","title":{"rendered":"Trying to avoid eval getting array element from window object-Collection of common programming errors"},"content":{"rendered":"<p>I&#8217;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:<\/p>\n<pre><code>function echoVar(whichone){\n  document.write(eval(whichone));\n}\n<\/code><\/pre>\n<p>I thought I&#8217;d just use the window[] syntax and have this:<\/p>\n<pre><code>function echoVar(whichone) {\n  document.write(window[whichone]);\n}\n<\/code><\/pre>\n<p>If I create a var and call it like this, it doc writes ABC as expected:<\/p>\n<pre><code>var abc = \"ABC\";\nechoVar(\"abc\");\n<\/code><\/pre>\n<p>If the var I want to access is an array element though, it doesn&#8217;t work:<\/p>\n<pre><code>var def = [\"DEF\"];\nechoVar(\"def[0]\");  \/\/fails with undefined\n<\/code><\/pre>\n<p>Obviously that&#8217;s actually executing window[def[0]] which rightly gives undefined (because there&#8217;s no variable called DEF). What I actually want to happen is that it executes window[&#8220;def&#8221;][0].<\/p>\n<p>The only way I know to achieve this, is to do a split on the whichone parameter with &#8220;[&#8221; 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:<\/p>\n<pre><code>function echoVar(whichone){\n  if(whichone.indexOf(\"[\")==-1){\n    document.write(window[whichone]);\n  }\n  else{\n    var s = whichone.split(\"[\");\n    var nam = s[0];\n    var idx = parseInt(s[1]);\n    document.write( window[nam][idx] );\n  }\n}\n<\/code><\/pre>\n<p>Am I overlooking something obvious? I&#8217;d rather keep the eval than have to do all that.<\/p>\n<ol>\n<li>\n<p>If you dislike using eval in your code, you can always do this:<\/p>\n<pre><code>function echoVar(whichone) {\n  document.write(Function(\"return \" + whichone)());\n}\n<\/code><\/pre>\n<\/li>\n<li>\n<p>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&#8217;t what you&#8217;re looking for, but it&#8217;s the right answer.<\/p>\n<\/li>\n<li>\n<p>The fact is you&#8217;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&#8217;s passed like this:<\/p>\n<pre><code>function echoVar(a,b) {\n    var x = window[a];\n    if (b) {\n        x = x[b];\n    }\n    document.write(x);\n}\n<\/code><\/pre>\n<p>And, then you can pass it differently like this:<\/p>\n<pre><code>var def = [\"DEF\"];\nechoVar(\"def\", 0);    \/\/ def[0]\n<\/code><\/pre>\n<p>You could even make this support multiple dimensions if you needed to.<\/p>\n<pre><code>function echoVar(a) {\n    var x = window[a];\n    for (var i = 1; i &lt; arguments.length; i++) {\n        x = x[arguments[i]];\n    }\n    document.write(x);\n}\n\nvar def = {myObject: {length: 3}}\nechoVar(\"def\", \"myObject\", \"length\");    \/\/ def[\"myObject\"][\"length\"] or def.myObject.length\n<\/code><\/pre>\n<p>You can see it work here: http:\/\/jsfiddle.net\/jfriend00\/dANwq\/<\/p>\n<\/li>\n<li>\n<p>It would be simpler to lose the brackets and call the item with dot notation<\/p>\n<pre><code>function reval(s, O){\n    s= String(s);\n    O= O || window;\n    var N= s.split(\".\");\n    while(O &amp;&amp; N.length) O= O[N.shift()];\n    return O || s;\n}\n\nwindow.def= ['definition'];\nalert(reval('def.0'))\n\n\/*  returned value: (String)\ndefinition\n*\/\n<\/code><\/pre>\n<\/li>\n<\/ol>\n<p id=\"rop\"><small>Originally posted 2013-11-09 19:45:29. <\/small><\/p>","protected":false},"excerpt":{"rendered":"<p>I&#8217;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&#8217;d just use the window[] syntax and have this: function echoVar(whichone) { document.write(window[whichone]); } If I create a var and call [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-486","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/486","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=486"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/486\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=486"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=486"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=486"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}