Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript eval in context without using this keyword

I am trying to execute eval within a particular context. I have found the answer here useful. However I am getting the following behavior in Chrome Version 53.0.2785.143 m. Not tried other browsers. The code I am using is the following:

function evalInContext(js, context) {
    return function() { return eval(js); }.call(context);
}


console.log(evalInContext('x==3', { x : 3})) // Throws
console.log(evalInContext('this.x==3', { x : 3})) // OK

However I expected the first call to evalInContext not to throw. Any ideas why this might be happening?

like image 617
Joe Avatar asked Dec 01 '22 12:12

Joe


2 Answers

whilst I recommend the answer provided by @trincot and in particular the great link. I am posting here my solution to the problem I faced

function evalInContext(scr, context)
{
    // execute script in private context
    return (new Function( "with(this) { return " + scr + "}")).call(context);
}

The with(this) expression allows the member variables of the context object to be present in the execution scope of the expression scr.

Credit to this answer to a similar question

like image 100
Joe Avatar answered Dec 04 '22 02:12

Joe


Scope and Context are not the same

The way variable x is resolved has nothing to do with context. It is resolved by scope rules: does any of the closures define that variable? If not, look in the global object. At no point the variable is resolved by looking in the context.

You could have a look at this article.

The behaviour is not particular to eval, it is the same with other functions:

"use strict";

var obj = { x : 3};
var y = 4;

function test() {
  console.log(this.x); // 3
  console.log(typeof x); // undefined
}

test.call(obj);

function test2() {
  console.log(this.y); // 4
  console.log(typeof y); // number
}

test2.call(window);
like image 26
trincot Avatar answered Dec 04 '22 01:12

trincot