为什么我不能复制函数的调用方法

时间:2019-07-03 08:33:46

标签: javascript function

本质上,我想包装(而不是扩展)一个函数,但包装器应像该函数一样可调用。我可以使用一个函数(示例1或2)来执行call函数。

我的问题是为什么我不能只复制call函数(示例3)?如果执行此操作,则会收到错误 Function.prototype.call在不兼容的对象上调用

function FunctionWrapper( description, functionReference ) {
    this.description = description;
    /* 1 */ this.call = function( thisArg ) { functionReference.call( thisArg ) };
    /* 2 */ this.call = thisArg => functionReference.call( thisArg );
    /* 3 */ this.call = functionReference.call;
}

function StringHolder( string ) {
    this.string = string;
}

StringHolder.prototype.log = function() {
    console.log( this.string );
};

let logger = new FunctionWrapper( "This is a logger", StringHolder.prototype.log );
logger.call( new StringHolder( "bar" ) );

1 个答案:

答案 0 :(得分:2)

#3的问题是this中的call是错误的。在#1和#2中,this中的callfunctionReference(传递给FunctionWrapper的函数),但是在#3中,this是{{1 }}实例,而不是FunctionWrapperfunctionReference期望call是一个函数对象,但是您的this不是函数,这就是为什么它会给您该错误消息的原因。 How does the "this" keyword work?中的更多内容。

如果您希望FunctionWrapper工作,则需要执行以下一项操作:

  • 使用#1,就很好了
  • 使用#2,这很好(我会说比#1更好)
  • 使用logger.call( new StringHolder( "bar" ));,例如:

    bind
  • 在对象上记住this.call = functionReference.call.bind(functionReference); ,并提供使用它的自己的functionReference

旁注:请不要忘记call的对应对象apply。 :-)