Subclassing Function
Nope, it's supposed to work. Object.getPrototypeOf(new SuperFunction("")
should be SuperFunction.prototype and new SuperFunction("") instanceof SuperFunction
should be true.
You need to file a bug report on the implementations where you tried it. Sounds like they still have some work to do
I filed one on us: code.google.com/p/v8/issues/detail?id=4087
On Thu, May 7, 2015 at 3:25 PM, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:
Nope, it's supposed to work.
Agreed. We're working on it in Firefox. It's of a piece with new.target support, so my best guess is it'll be weeks, maybe a couple months, before it lands in Nightly.
While creating functions from strings is useful, I would much prefer being able to define call and construct methods in the source. Something like:
class SubFunction extends Function {
// Assigned as internal [[Call]] property.
[Symbol.functionCall]() {
return true
}
// Optional [[Construct]] override. If included, will be used instead of
// [[Call]] when called with `new`.
[Symbol.construct]() {
// ...
}
}
const Sub = new SubFunction()
Sub()
new Sub()
On second thought, a construct method wouldn't add anything that classes don't do better. Let's just stick with call:
class SubFunction extends Function {
someState = {}
// Assigned as internal [[Call]] property.
[Symbol.functionCall]() {
// ...
}
someMethod() {
// ...
}
}
const sub = new SubFunction()
sub()
Why not check new.target
?
function SubFunction() {
// function call
if (new.target === undefined) {
}
// constructor call
else {
}
}
Separate methods can be decorated. Which raises the question whether the proposal is compatible with decorators in their current state.
Perhaps you would be interested in the current proposal for Call Constructors tc39/ecma262/blob/master/workingdocs/callconstructor.md ?
@Jordan The linked proposal is what inspired the dual-method part (which I backed away from) of my suggestion.
How we define the call/construct methods of a class is actually orthogonal to how we define the call method of an instance of the hypothetical function subclass. If anything, they have to be keyed separately. Example:
class SubFunction extends Function {
constructor() {
// "static" constructor function, sets up instance state
}
call constructor() {
// hypothetical "static function" version of class
}
[Symbol.functionCall]() {
// body of class instance function
}
}
In the existing implementations I’ve tried, it appears I can’t do this:
(also tried with
constructor(str) { super(str) }
)It “works”, but the resulting
new SuperFunction("return 5")
is just a Function, not a SuperFunction. Is Function meants to be an exception to the subclassing built-ins, or should it also work?