expr-eval icon indicating copy to clipboard operation
expr-eval copied to clipboard

`this` broken on functions in objects

Open adri326 opened this issue 7 years ago • 1 comments

While playing around, I saw an issue with the module, which is that when accessing functions in objects (with Parser.prototype.evaluate), these function lost their this.

Example:

// requires and everything

const variables = {
  x: {
    y: function() {
      console.log(this.z);
    },
    z: "Moo!"
  }
}

variables.x.y(); // prints out "Moo!"

const parser = new exprEval.Parser();

parser.parse("x.y()").evaluate(variables); // prints out `undefined`

(parser.parse("x.y").evaluate(variables))(); // prints out `undefined`
(parser.parse("x").evaluate(variables)).y(); // prints out "Moo!"

This issue becomes problematic when handling class instances or arrays in the variables, since you will not be able to access methods such as Array.prototype.pop().

adri326 avatar Jul 05 '18 15:07 adri326

I'll need to think about the best way to solve this. Right now, the evaluator doesn't have any concept of "this", and I'm not sure I want to introduce that kind of complexity. There's also no concept of a method call, so x.y() is effectively the same as doing something like var f = x.y; f() (not actual code, since it doesn't currently support assignment).

Just thinking "out loud", probably the simplest thing to do would be to automatically bind functions when they're accessed through objects. It's probably not the most efficient method, but it seems like the most effective way to hide "this" and avoid having to change the execution model too much.

silentmatt avatar Jul 06 '18 19:07 silentmatt