In the following code,
class PersonClass {
constructor(fname) {
this.fname = fname;
}
read = function() { console.log('I am reading') }
speak () { console.log('I am speaking'); }
}
//Instantiate
let p1 = new PersonClass('Raj')
read = function() { console.log('I am reading') }
becomes a property of newly created instance i.e.
p1.hasOwnProperty('read')
is true
as opposed to speak() { console.log('I am speaking'); }
gets assigned to PersonClass.prototype
. i.e.
p1.hasOwnProperty('speak')
is False
p1.__proto__.hasOwnProperty('speak')
is true
Can somebody pls explain why this happens.
Essentially what's the diff between two way of method declarations inside class.
I thought speak() {...}
was just shorter syntax for speak = function() {...}
(in ES6)
Thanks
The
read = function() { console.log('I am reading') }
is new class field syntax. It's effectively the same as assigning to the read
property of the instance inside the constructor:
class PersonClass {
constructor(fname) {
this.read = function() {
console.log('I am reading')
}
this.fname = fname;
}
speak() {
console.log('I am speaking');
}
}
speak
, on the other hand, is an ordinary class method, which means it's on the prototype, PersonClass.prototype
, which is the same thing as Object.getPrototypeOf(p1)
, which is the same thing as p1.__proto__
(deprecated syntax).
class PersonClass {
constructor(fname) {
this.read = function() {
console.log('I am reading')
}
this.fname = fname;
}
speak() {
console.log('I am speaking');
}
}
let p1 = new PersonClass('Raj')
console.log(
PersonClass.prototype.hasOwnProperty('speak'),
Object.getPrototypeOf(p1) === PersonClass.prototype,
p1.__proto__ === PersonClass.prototype
);
So, the speak
property is on the internal prototype of the instance, not on the instance itself. The read
property is a direct property of the instance, just like the fname
property.
Keep in mind that class field syntax is still an experimental proposal (stage 3). It's implemented in Chrome, at least, but it's not completely official yet.