diff --git a/src/jsep-eval.js b/src/jsep-eval.js index eb48f66..44bda5c 100644 --- a/src/jsep-eval.js +++ b/src/jsep-eval.js @@ -136,8 +136,12 @@ const evaluateExpressionNode = (node, context) => { case types.CALL : { assert(_.includes([types.MEMBER, types.IDENTIFIER, types.THIS], node.callee.type), 'Invalid function callee type'); const callee = evaluateExpressionNode(node.callee, context); + let object = null; + if (node.callee.type === types.MEMBER) { + object = evaluateExpressionNode(node.callee.object, context); + } const args = _.map(node.arguments, arg => evaluateExpressionNode(arg, context)); - return callee.apply(null, args); + return callee.apply(object, args); } case types.IDENTIFIER: // !!! fall-through to MEMBER !!! // case types.MEMBER: { diff --git a/test/jsep-eval.test.js b/test/jsep-eval.test.js index e1e1a72..b3eacc7 100644 --- a/test/jsep-eval.test.js +++ b/test/jsep-eval.test.js @@ -37,6 +37,16 @@ describe('======== ' + name + ' =========', () => { const ctx = {a: () => 2}; expect(evaluate(exp, ctx)).to.equal(2); }); + it(name + ': evaluate a call expression on an array from context with this', () => { + const exp = 'this.a.indexOf(2)'; + const ctx = {a: [1, 2, 3]}; + expect(evaluate(exp, ctx)).to.equal(1); + }); + it(name + ': evaluate a call expression on an array from context without this', () => { + const exp = 'a.indexOf(2)'; + const ctx = {a: [1, 2, 3]}; + expect(evaluate(exp, ctx)).to.equal(1); + }); it(name + ': evaluate a call expression with an arg', () => { const exp = 'a(b)'; const ctx = {a: arg => 2 * arg, b: 3};