javascript eval in global scope

07 Nov 2008

Yeah I know, sprintf one day, and javascript the next. That's how I roll.

Short answer

By default, eval runs in the local scope. To do an eval in the global scope do this trick:

eval.call(null, script);

Long Answer

This is a bit esoteric, and eval is not something you should use very often (if at all) in normal client-side programming.

A HTML browser when seeing a <code> tag, either loads the src url or the script body and does an internal eval at the global scope.

For example, let's say in your XMLHttpRequest passed back some javascript. How can you eval it in the global scope? I'm not recommending this pattern but for instance

function http_callback(ascript) {
    eval(ascript);
}

If the callback text is something like "var x = 1;", then the eval(text) just makes a local variable just like either of these functions:

js> function f_local() { var x = 1; }
js> f_local();
typein:10: ReferenceError: x is not defined
js> function f_local_eval() { eval('var x = 1;'); }
js> f_local_eval();
typein:12: ReferenceError: x is not defined

Eval doesn't have an option to run in the global scope, which seems odd at first. Javascript is kinda cool since even built-in functions such as parseInt, and yes, eval are a true javascript function. And if you poke around in the Function methods you'll find the call method. If the first arg is null then it runs in the global scope. Finally we have eval.call(null, script_text) as the magic invocation.

js> x
typein:24: ReferenceError: x is not defined
js> function f_global_eval() { eval.call(null, "var x = 1;"); }
js> f_global_eval();
js> x
1

ta-da!


Comment 2008-11-30 by None

Excellent article and well argumented. But as often IE is breaking ranks. This article covers that case. To me an optimal solution looks like this:

var evalCode = function(code) {
  if (window.execScript) window.execScript(code);
  else eval.call(null, code);
};


Comment 2008-12-03 by None

hie, i am also using eval but i face an issue in firefox, actually i am using it something like this

var evalCode = function(code) {
//alert(code);
if (window.execScript) window.execScript(code);
else eval(unescape(code));
//alert("code executed..");
};

function ShowUploadPopUp() {
//alert("OK.");
evalCode(document.getElementById("JScriptCall").innerHTML);
}
where JScriptCall is span element in which i write the following lines from code behind using C# with ASP.Net

<span id="JScriptCall" class="DisplayNone">
window.open('test.aspx?uid=MzU5-OlWfO7Q3&catid=NDUGM67ISI', 'page', 'toolbar=0, scrollbars=1, location=0, statusbar=0, menubar=0, resizable=0, width=600, height=410, left=50, top=50, titlebar=yes');
</span>

but when i use it in firefox, it opens the window but the url created is not right.
it convets '&' to '& amp;' (without space) because of which i can not get the values of the querystring....

any help, how can i keep ascii charaters in the querystring using eval function...


Comment 2009-06-18 by None

Great! You save my morning, Thanks