Setting properties of super, such as super.x = 1, behaves like Reflect.set(Object.getPrototypeOf(objectLiteral), "x", 1, this). This is one of the cases where understanding super as simply "reference of the prototype object" falls short, because it actually sets the property on this instead.
class A {}
class B extends A {
setX() {
super.x = 1;
}
}
const b = new B();
b.setX();
console.log(b);
console.log(Object.hasOwn(b, "x"));
super.x = 1 will look for the property descriptor of x on A.prototype (and invoke the setters defined there), but the this value will be set to this, which is b in this context. You can read Reflect.set for more details on the case when target and receiver differ.
This means that while methods that get super.prop are usually not susceptible to changes in the this context, those that set super.prop are.
const b2 = new B();
b2.setX.call(null);
However, super.x = 1 still consults the property descriptor of the prototype object, which means you cannot rewrite non-writable properties, and setters will be invoked.
class X {
constructor() {
Object.defineProperty(this, "prop", {
configurable: true,
writable: false,
value: 1,
});
}
}
class Y extends X {
constructor() {
super();
}
foo() {
super.prop = 2;
}
}
const y = new Y();
y.foo();
console.log(y.prop);