为什么这些类实现没有相同的行为?

时间:2017-06-27 02:51:49

标签: javascript function call metaprogramming

我试图为扩展Function的类编写概念证明,以演示可以基于另一个函数初始化的函数构造函数,并反映this和{{1}以下列方式:

arguments

但是,根据我对class Handle extends Function { constructor(functor) { super("functor", "slice", ` "use strict"; return functor .call(this, ...slice.call(arguments, 2)); `); return this.bind(this, functor, Array.prototype.slice) } } let handle = new Handle(function test() { console.log(this instanceof Handle, arguments.length) }) console.log(handle instanceof Handle, handle.length) handle(1, 2, 3)call的理解,我认为这会产生相同的行为:

apply

抛出

class Handle extends Function {
  constructor(functor) {
    super("instance", "call", "slice", `
      "use strict";
      return call(this, instance, ...slice.call(arguments, 3));
    `);

    return Function.bind
      .call(this, functor, this, Function.call, Array.prototype.slice)
  }
}

let handle = new Handle(function test() {
  console.log(this instanceof Handle, arguments.length)
})

console.log(handle instanceof Handle, handle.length)

handle(1, 2, 3)

所以Uncaught TypeError: call is not a function at Function.eval (eval at Handle (js:4), <anonymous>:5:14) 函数出了问题。我的理解是,如果call()不是调用表达式的一部分,它的第一个参数将成为被调用的函数,其余的参数将成为函数的上下文和参数,类似于{ {1}}会这样做:

call()

有人可以解释我的误解,或者为什么看起来不是这样?

2 个答案:

答案 0 :(得分:1)

在没有Function.call的情况下,您正在呼叫Function.prototype.call(我认为this会更正确)。但它需要一个,因为this值是它调用的函数。问题的一个较短的例子:

var call = Function.prototype.call;
call();

也许您打算call.call(this, …)

&#13;
&#13;
class Handle extends Function {
  constructor(functor) {
    super("instance", "call", "slice", `
      "use strict";
      return call.call(this, instance, ...slice.call(arguments, 3));
    `);

    return Function.bind
      .call(this, functor, this, Function.call, Array.prototype.slice)
  }
}

let handle = new Handle(function test() {
  console.log(this instanceof Handle, arguments.length)
})

console.log(handle instanceof Handle, handle.length)

handle(1, 2, 3)
&#13;
&#13;
&#13;

答案 1 :(得分:1)

Uncaught TypeError: call is not a function
     

所以call()函数出了问题。

请注意,this message is misleadingcall不是call,而是this试图调用的东西。

  

我的理解是如果call()不是调用表达式的一部分,它的第一个参数将成为被调用的函数

没有。被调用的函数始终是call调用的call上下文,当call.call(functor, context, ...args)未作为方法调用时,没有任何改变。您需要table created