Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

calling eval() in particular context

Tags:

javascript

I have following javaScript "class":

A = (function() {    a = function() { eval(...) };    A.prototype.b = function(arg1, arg2) { /* do something... */}; })(); 

Now let's assume that in eval() I'm passing string that contains expression calling b with some arguments:

 b("foo", "bar") 

But then I get error that b is not defined. So my question is: how to call eval in context of class A?

like image 363
mnowotka Avatar asked Dec 06 '11 16:12

mnowotka


People also ask

Why eval () is the evil?

eval() is evil if running on the server using input submitted by a client that was not created by the developer or that was not sanitized by the developer. eval() is not evil if running on the client, even if using unsanitized input crafted by the client.

What is the purpose of the eval () method?

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


1 Answers

Actually you can accomplish this with an abstraction via a function:

var context = { a: 1, b: 2, c: 3 };  function example() {     console.log(this); }  function evalInContext() {     console.log(this);        //# .logs `{ a: 1, b: 2, c: 3 }`     eval("example()");        //# .logs `{ a: 1, b: 2, c: 3 }` inside example() }  evalInContext.call(context); 

So you call the function with the context you want and run eval inside that function.

Oddly, this seems to be working for me locally but not on Plunkr!?

For a succinct (and arguably succulent ;) version you can copy verbatim into your code, use this:

function evalInContext(js, context) {     //# Return the results of the in-line anonymous function we .call with the passed context     return function() { return eval(js); }.call(context); } 

EDIT: Don't confuse this and "scope".

//# Throws an error as `this` is missing console.log(evalInContext('x==3', { x : 3}))  //# Works as `this` is prefixed console.log(evalInContext('this.x==3', { x : 3}))  

While one could do this:

function evalInScope(js, contextAsScope) {     //# Return the results of the in-line anonymous function we .call with the passed context     return function() { with(this) { return eval(js); }; }.call(contextAsScope); } 

to bridge the gap, it's not what OP's question asked and it uses with, and as MDN says:

Use of the with statement is not recommended, as it may be the source of confusing bugs and compatibility issues. See the "Ambiguity Contra" paragraph in the "Description" section below for details.

But it does work and isn't too "bad" (whatever that means), so long as one is aware of the oddnessess that can arise from such a call.

like image 126
Campbeln Avatar answered Sep 21 '22 12:09

Campbeln