I'm working on getting https://github.com/donmccurdy/expression-eval to properly support expressions containing this
.
The module defines a function:
function evaluate ( node, context ) {
...
}
It exports it as eval
:
module.exports = {
parse: jsep,
eval: evaluate,
compile: compile
};
In my code, I define a local context for this
and call expr.eval
:
const expr = require( 'expression-eval' );
function test() {
console.log( this ); // outputs the right thing
var context = { baz: 'blah' };
var ast = expr.parse( 'this.A + baz' );
var val = expr.eval( ast, context );
console.log( val ); // outputs "undefinedbaz"
}
test.apply( { A: 'aay', B: 'bee } );
Inside of evaluate()
I inserted console.log( this )
. Initially, it was the global object. I added 'use strict';
and it changed to undefined
.
I've tried everything I can think of to get the value of this
to have the right value inside of the evaluate
function:
var fn = expr.eval.bind( this );
fn( ast, context );
and
expr.eval.apply( this, [ ast, context ] );
Nothing works. It's almost as if require
is doing something BAD which is breaking the ability to use .apply
How do I fix this?
It turns out that in JavaScript, whenever you call a function (as opposed to an object method), unless you use .bind()
, .call()
, or .apply()
, the value of this
is always lost. Who knew?
The solutions include:
1) in your recursive function, recurse using .call()
function silly(i) {
if ( i < 1 ) // do something with this
else return silly.call( this, i-1 );
}
2) wrap your function and save this
for reference
function silly(i) {
var localThis = this;
function s(i) {
if ( i < 1 ) // do something with localThis
else return s( i-1 );
}
return s(i);
}