Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using eval() with a custom global

Is there a way to specify which object to use for global when invoking eval()?

(I'm not asking how to do global eval().)

This is not working but this illustrates what I would like:

var pseudoGlobal = {};
eval("x = 12", pseudoGlobal);
pseudoGlobal.x; // 12

The point is that real global bindings are not affected by implicit variable declaration (i.e. without var keywords) in the code eval()'ed.

As for eval.call(pseudoGlobal, "x=12") or eval.apply(pseudoGlobal, ["x=12"]), some interpreters wont allow it.

like image 285
gawi Avatar asked Jun 15 '12 12:06

gawi


2 Answers

You can, of course, substitute default object for assigning a property value, like in

with (pseudoGlobal) eval("x=12")

but not for creating a propery. If a property is not found in the current stack of execution contexts, it's created in the global object. That's all there is to it. You might try some weird things, also:

//global code
var globalvars = {};
for (i in this)
    globalvars[i] = null;
with (pseudoGlobal) 
    eval("x=12")
for (i in this)
    if (!(i in globalvars))
{
    pseudoGlobal[i] = this[i];
    delete this[i];
}

If you care about global bindings, try:

var globalvars = {};
for (i in this)
    globalvars[i] = this[i];
with (globalvars) 
    eval("x=12")

this way the bindings will be changed in globalvars. Note, that shallow copy will prevent only one level of bingings to change.

like image 99
panda-34 Avatar answered Oct 27 '22 04:10

panda-34


There is no built-in way to do this.

There are two solutions that come to mind:

  • Prefix all assignments in the evaled code. i.e., instead of x = 12, you would have to do something like o.x = 12.
  • Write your own Javascript interpreter that sandboxes the script and returns an object with all the assigned variables.
like image 39
Peter Olson Avatar answered Oct 27 '22 05:10

Peter Olson