The super attribute cannot be accessed, but can be modified?
What does super
stand for? Some people say it is prototype? I know that the function of Class is in the prototype of the object, but why can super.name ='Lucy';
modify the properties of the object instance?
class a { name = 'jack'; speak() { console.log(this.name); } } class b extends a { count() { super.name = 'Lucy'; console.log(super.name) // undefined super.speak(); } } new b().count(); // Lucy
Advertisement
Answer
Assigning to super.prop
is useful when prop
is defined on the parent’s prototype, not when it is defined as an instance property, as is the case with name
in your code. Realise that the assignment name = 'jack'
happens on the instance that is created by new b
, not on some other object.
So when you do super.name = 'Lucy'
, you are doing nothing else than this.name = 'Lucy'
. This change is not visible when you consult super.name
after that assignment, because that will scan the parent’s prototype chain, not the instance object. And there is no name
defined anywhere on that prototype chain…
The difference between how super.name
acts when used for lookup and for assignment is specific: for (non-setter) assignment, it is no different than assigning on this
, while for lookup (including setter lookup), it skips this
and starts the lookup in the parent’s prototype chain.
The power of the super.prop
syntax only reveals itself when you have to deal with methods that have been created on the prototype.
To demonstrate this, let’s define name
as a getter/setter function on the prototype:
class A { _name = 'jack'; speak() { console.log(this.name); } get name() { return this._name; } set name(name) { return this._name = name + " (A)"; } } class B extends A { count() { super.name = 'Lucy'; // This will not call the setter of B.prototype, but of A.prototype super.speak(); } get name() { return this._name; } set name(name) { return this._name + " (B)"; } } new B().count(); // Lucy (A)
Note that here super.name
is first identified to be a function in the upper prototype chain, and thus the assignment becomes a function call. If it would have been a property-modifying assignment, it would have happened on this
.
See for an elaborate analysis of the specification in this respect in this answer to “ES6 inheritance: uses super
to access the properties of the parent class”