I have a file with the following code:
class Animal {
doSomething = () => {
return 'Hi.';
};
}
class Dog extends Animal {
doSomething = () => {
return super.doSomething() + ' Woof!';
};
}
console.log(new Dog().doSomething());
Note: trying to run the snippet above probably won't work because I can't figure out how to make it use my Babal settings.
Anyway, when I compile it using Babel and run it in Node, I get the following error:
/Users/elias/src/classFieldTest/build/classFieldTest.js:15
return super.doSomething() + ' Woof!';
^
TypeError: (intermediate value).doSomething is not a function
at Dog.doSomething (/Users/elias/src/classFieldTest/build/classFieldTest.js:15:26)
at Object.<anonymous> (/Users/elias/src/classFieldTest/build/classFieldTest.js:21:23)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
at Function.Module.runMain (module.js:693:10)
at startup (bootstrap_node.js:188:16)
at bootstrap_node.js:609:3
I am using Babel 6.26.0 with the stage-2 preset, and Node 8.11.1. I can show the commands I'm using if anyone cares.
Why is this happening? I am guessing that super can't be used to access a class field, but what am I supposed to do about this? If I change the doSomething method of Animal to a traditional method (doSomething() { return 'Hi.'; }), it works, but I would rather avoid traditional methods, with the way they redefine this and all the confusion it causes.
Is there any way to access a class field of a superclass?
Why is this happening? I am guessing that super can't be used to access a class field
Yes. Class fields are instance properties, but super tries to access properties on the superclass' prototype object. Your Animal class simply doesn't have a doSomething method - instead, every Animal object has a property that contains a bound function.
but what am I supposed to do about this? If I change it to a traditional method, it works
Yes, you are supposed to do exactly that. This is how methods and super work.
Avoid arrow functions when you don't need them, and especially when they don't work. Also have a look at Arrow Functions in Class Properties Might Not Be As Great As We Think.
Is there any way to access a class field of a superclass?
Yes - it is an instance property, and you can access it in your constructor before overwriting it:
class Animal {
constructor() {
this.doSomething = () => {
return 'Hi.';
};
}
}
class Dog extends Animal {
constructor() {
super();
const superDoSomething = this.doSomething;
this.doSomething = () => {
return superDoSomething() + ' Woof!';
};
}
}
Alternatively, with the class fields proposal and no explicit constructor:
class Animal {
doSomething = () => {
return 'Hi.';
}
}
class Dog extends Animal {
doSomething = (superDoSomething => () => {
return superDoSomething() + ' Woof!';
})(this.doSomething)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With