Function.apply(x)/.bind(x) 导致 `this` 为 `undefined`

Function.apply(x)/.bind(x) results in `this` being `undefined`

我正在努力让 https://github.com/donmccurdy/expression-eval 正确支持包含 this 的表达式。

模块定义函数:

function evaluate ( node, context ) {
  ...
}

导出为 eval:

module.exports = {
  parse: jsep,
  eval: evaluate,
  compile: compile
};

在我的代码中,我为 this 定义了一个本地上下文并调用 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 } );

我在 evaluate() 中插入了 console.log( this )。最初,它是全局对象。我添加了'use strict';,它变成了undefined

我已经尝试了所有我能想到的方法来获取 this 的值,以便在 evaluate 函数中获得正确的值:

var fn = expr.eval.bind( this );
fn( ast, context );

expr.eval.apply( this, [ ast, context ] );

没有任何效果。就好像 require 正在做一些坏事,这破坏了使用 .apply

的能力

我该如何解决这个问题?

事实证明,在 JavaScript 中,无论何时调用函数(与对象方法相反),除非使用 .bind().call().apply(), this 的值总是丢失。谁知道?

解决方案包括:

1) 在你的递归函数中,使用 .call()

递归
function silly(i) {
  if ( i < 1 ) // do something with this
  else return silly.call( this, i-1 );
}

2) 包装你的函数并保存 this 以供参考

function silly(i) {
  var localThis = this;
  function s(i) {
    if ( i < 1 ) // do something with localThis
    else return s( i-1 );
  }
  return s(i);
}