-
Hello, I ran into an issue with using arrow functions as class members, and was curious about node's current behavior. We had been using babel-plugin-transform-class-property-arrow-functions and removed it when node handled arrow functions natively. But now I noticed that node's behavior is different from the babel plugin. It seems to not assign the function to the class prototype, so calls to super fail. If I manually bind the function in the constructor, it seems to work fine. Is there a reason node doesn't do it this way? Is this a bug or going to be changed in the future? Putting the function on the class seems like the expected behavior considering other OO languages treatment of super - though, in my example below, we certainly end up with multiple nested unnecessary bind() calls. Thanks, I am running node 16.13.2. Here is an example program: // Binding onError to this to allow something like subscription.on( 'error', this.onError ) and subscription.off( 'error', this.onError )
class BadParent {
onError = ( ) => {
console.log( 'BadParentError' )
}
}
class BadChild extends BadParent {
onError = ( ) => {
console.log( 'BadChildError' )
super.onError()
}
}
class Parent {
constructor() {
this.onError = this.onError.bind( this )
}
onError( ) {
console.log( 'ParentError' )
}
}
class Child extends Parent {
constructor() {
super()
this.onError = this.onError.bind( this )
}
onError( ) {
console.log( 'ChildError' )
super.onError()
}
}
class SubChild extends Child {
constructor() {
super()
this.onError = this.onError.bind( this )
}
onError( ) {
console.log( 'SubChildError' )
super.onError()
}
}
const bad = new BadChild()
const good = new Child()
const good2 = new SubChild()
try {
console.log( '------- Bad' )
bad.onError()
} catch ( ex ) {
console.log( ex )
}
try {
console.log( '------- Good' )
good.onError()
} catch ( ex ) {
console.log( ex )
}
try {
console.log( '------- SubChild' )
good2.onError()
} catch ( ex ) {
console.log( ex )
} The result is:
|
Beta Was this translation helpful? Give feedback.
Replies: 0 comments 2 replies
-
I think that's because the Babel plugin you were using was not ECMAScript compliant, const arrowFn = () => {};
class Parent {
t() {} // Prototype method.
t = arrowFn; // Class field.
}
new class extends Parent {
t = () => console.log(
super.t === Parent.prototype.t, // super.t refers to the prototype method
super.t !== arrowFn, // not to the arrow function defined property
);
}().t();
console.log(new Parent().t === arrowFn); // even though the class field has "higher priority" in other context.
The proposal has reached stage 4 and has been merged to the ECMAScript spec, it's safe to say it's not going to change. |
Beta Was this translation helpful? Give feedback.
I think that's because the Babel plugin you were using was not ECMAScript compliant,
super.onError
cannot refer to a class field function:The proposal has reached stage 4 and has been merged to the ECMAScript …