为什么这些 class 实现没有相同的行为?
Why don't these class implementations have identical behavior?
我试图为扩展 Function
的 class 编写概念证明,以演示可以基于另一个函数初始化的函数构造函数,并反映 this
和 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()
函数有问题。我的理解是,如果 call()
不是调用表达式的一部分,它的第一个参数将成为被调用的函数,其余参数将成为函数的上下文和参数,有点像 Function.call.call(this, instance, ...slice.call(arguments, 3))
会做:
class Handle extends Function {
constructor(functor) {
super("instance", "call", "slice", `
"use strict";
return Function.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)
谁能解释一下我的误解,或者为什么情况似乎并非如此?
您正在调用 Function.call
(我认为使用 Function.prototype.call
会更正确)而没有 this
。不过,它需要一个,因为 this
值是它调用的函数。该问题的一个较短示例:
var call = Function.prototype.call;
call();
也许你打算 call.call(this, …)
?
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)
Uncaught TypeError: call is not a function
so it's something wrong with the call() function.
请注意 ,不是 call
不是函数,而是 call
试图调用的东西。
My understanding was that if call() wasn't part of a call expression, its first argument would become the function being called
没有。被调用的函数始终是 call
调用的 this
上下文,当 call
未作为方法调用时,没有任何改变。你需要做 call.call(functor, context, ...args)
.
我试图为扩展 Function
的 class 编写概念证明,以演示可以基于另一个函数初始化的函数构造函数,并反映 this
和 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()
函数有问题。我的理解是,如果 call()
不是调用表达式的一部分,它的第一个参数将成为被调用的函数,其余参数将成为函数的上下文和参数,有点像 Function.call.call(this, instance, ...slice.call(arguments, 3))
会做:
class Handle extends Function {
constructor(functor) {
super("instance", "call", "slice", `
"use strict";
return Function.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)
谁能解释一下我的误解,或者为什么情况似乎并非如此?
您正在调用 Function.call
(我认为使用 Function.prototype.call
会更正确)而没有 this
。不过,它需要一个,因为 this
值是它调用的函数。该问题的一个较短示例:
var call = Function.prototype.call;
call();
也许你打算 call.call(this, …)
?
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)
Uncaught TypeError: call is not a function
so it's something wrong with the call() function.
请注意 call
不是函数,而是 call
试图调用的东西。
My understanding was that if call() wasn't part of a call expression, its first argument would become the function being called
没有。被调用的函数始终是 call
调用的 this
上下文,当 call
未作为方法调用时,没有任何改变。你需要做 call.call(functor, context, ...args)
.