Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Specify scope for eval() in JavaScript?

is there any way I can execute eval() on a specific scope (but NOT global)?

for example, the following code doesn't work (a is undefined on the second statement) because they are on different scope:

eval(var a = 1);  eval(alert(a)); 

If possible, I would like to create a scope on the fly. for example (the syntax is definitely wrong, but just to illustrate the idea)

var scope1; var scope2; with scope1{     eval(var a = 1); eval(alert(a));  // this will alert 1 } with scope2{     eval(var a = 1); eval(a++); eval(alert(a));  // this will alert 2 } with scope1{     eval(a += 2); eval(alert(a)); // this will alert 3 because a is already defined in scope1 } 

Any idea on how to achieve something like this? Thanks!

like image 477
hiukim Avatar asked Mar 20 '12 04:03

hiukim


People also ask

What does eval () do in JavaScript?

The eval() function evaluates JavaScript code represented as a string and returns its completion value. The source is parsed as a script.

What is the use of eval () function give example?

What is eval () in python and what is its syntax? Answer: eval is a built-in- function used in python, eval function parses the expression argument and evaluates it as a python expression. In simple words, the eval function evaluates the “String” like a python expression and returns the result as an integer.

What can I use instead of eval in JavaScript?

An alternative to eval is Function() . Just like eval() , Function() takes some expression as a string for execution, except, rather than outputting the result directly, it returns an anonymous function to you that you can call. `Function() is a faster and more secure alternative to eval().


2 Answers

you can use the "use strict" to contain the eval'ed code within the eval itself.

Second, eval of strict mode code does not introduce new variables into the surrounding scope. In normal code eval("var x;") introduces a variable x into the surrounding function or the global scope. This means that, in general, in a function containing a call to eval every name not referring to an argument or local variable must be mapped to a particular definition at runtime (because that eval might have introduced a new variable that would hide the outer variable). In strict mode eval creates variables only for the code being evaluated, so eval can't affect whether a name refers to an outer variable or some local variable

var x = 17;                                       //a local variable var evalX = eval("'use strict'; var x = 42; x");  //eval an x internally assert(x === 17);                                 //x is still 17 here assert(evalX === 42);                             //evalX takes 42 from eval'ed x 

If a function is declared with "use strict", everything in it will be executed in strict mode. the following will do the same as above:

function foo(){     "use strict";       var x = 17;      var evalX = eval("var x = 42; x");      assert(x === 17);      assert(evalX === 42); } 
like image 107
Joseph Avatar answered Oct 10 '22 07:10

Joseph


Create the variables you want to exist in your scope as local variables in a function. Then, from that function, return a locally-defined function that has a single argument and calls eval on it. That instance of eval will use the scope of its containing function, which is nested inside the scope of your top level function. Each invocation of the top level function creates a new scope with a new instance of the eval function. To keep everything dynamic, you can even use a call to eval in the top level function to declare the variables that will be local to that scope.

Example code:

function makeEvalContext (declarations) {     eval(declarations);     return function (str) { eval(str); } }  eval1 = makeEvalContext ("var x;"); eval2 = makeEvalContext ("var x;");  eval1("x = 'first context';"); eval2("x = 'second context';"); eval1("window.alert(x);"); eval2("window.alert(x);"); 

https://jsfiddle.net/zgs73ret/

like image 33
Periata Breatta Avatar answered Oct 10 '22 05:10

Periata Breatta