I know one of the difference is that instance variables of type Function automatically bind to the class. For example:
class Dog { sound = 'woof' bark() { console.log(this) } boundBark = () => { console.log(this) } } const fido = new Dog() fido.bark() // woof fido.boundBark() // woof const bark = fido.bark bark() // undefined const boundBark = fido.boundBark boundBark() // woof
Dog { sound: 'woof', boundBark: [Function: boundBark] } Dog { sound: 'woof', boundBark: [Function: boundBark] } undefined Dog { sound: 'woof', boundBark: [Function: boundBark] }
Why is this and are there other difference between these two ways of writing an instance function?
Advertisement
Answer
You can check what these ways are acting on the Dog.prototype
object:
Method definition:
class Dog { bark() { console.log(this) // *this* referss to the actual instance } } console.log(Dog.prototype.bark); // function bark
class Dog { bark = () => { console.log(this); // also, *this* refers to the actual instance } } console.log(Dog.prototype.bark); // undefined
In the first case you define a function in the class prototype, while in the latter you define the variable in the instance at “constructor time”, as for any other variable.
The latter is the same as doing:
class Dog { constructor() { this.bark = () => { // this is the reason why *this* is actually available // and refers to the actual instance console.log(this); } /* The rest of defined constructor */ } } console.log(Dog.prototype.bark); // undefined
Remember that the Public class field
s are still not introduced in the ECMAs
standards, so many JS environments could not support them, you should use some tools like Babel in order to achieve back compatibility. Some behaviours are still application dependant for this reason (like definition precedence).