I was attempting to write a proof of concept for a class that extends Function
in order to demonstrate a function constructor that could be initialized based on another function, and reflect this
and arguments
in the following manner:
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)
However, I thought that this would produce identical behavior based on my understanding of call
and 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)
This throws
Uncaught TypeError: call is not a function
at Function.eval (eval at Handle (js:4), <anonymous>:5:14)
so it's something wrong with the call()
function. My understanding was that if call()
wasn't part of a call expression, its first argument would become the function being called and the rest of the arguments would then become the context and the arguments of the function, sort of like Function.call.call(this, instance, ...slice.call(arguments, 3))
would do:
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)
Can someone explain what I'm misunderstanding, or why this does not appear to be the case?