hui
hui

Reputation: 601

“super” can call the base class method and property

in es6,"super" can call the base class like:

class A{
  constructor(){
    this.p = 2;
  }
  initF(){
    return this.p
  }
}

class B extends A{
  constructor(){
    super();
    console.log(super.p); // undefined
    console.log(super.initF()); // 2
  }
  ff(){
    console.log(super.initF()); // 2
  }
}

new B().ff();

It is obvious that we just can call the base class (A) method, we can't call the prototype. why can't access the base class prototype by "super"?

Upvotes: 1

Views: 783

Answers (2)

Jyothi Babu Araja
Jyothi Babu Araja

Reputation: 10282

The super keyword is used to call functions on an object's parent.

The super.prop and super[expr] expressions are valid in any method definition in both classes and object literals.

You can access parent properties by using this but only after calling super() in base class constructor

For more read here

class A{
  constructor(){
    this.p = 2;
  }
  initF(){
    return this.p
  }
}

class B extends A{
  constructor(){
    super();
    console.log(super.p); // invalid = undefined
    console.log(super().p); // valid = 2
    console.log(super.initF()); // 2
  }
  ff(){
    console.log(super.initF()); // 2
  }
}
new B().ff();

Upvotes: 1

Stefan Rein
Stefan Rein

Reputation: 9046

Actually you can.

To answer your question: JavaScript does not put the property inherited on the prototype chain. If you want to, you need to set it yourself: A.prototype.p = 5

If you inherit from another class, your methods will be put on the prototype, so they will be shared across classes and you can overwrite the method from the base class. That's good.

Now if you inherit, you need to call super(); Then the constructor of the base class will be called and you can access the property with: this.p instead of super.p. Because then, you would change the property (in the prototype) for all the (next) inherited classes - but that's not what we want. We want this for each class, which inherit an own property.

Maybe you take a look at TypeScript. You could write less with more syntactic sugar.

class A {
  constructor(){
    this.p = 2;
  }
  initF(){
    return this.p
  }
}

class B extends A {
  constructor(){
    super();
    console.log("super.constructor.prototype: ", super.constructor.prototype);
    console.log("super.constructor.prototype.p: ", super.constructor.prototype.p);
    console.log('A.prototype.p', A.prototype.p);
    console.log('this.__proto__.', this.__proto__.p);
    console.log('super.p', super.p);
    console.log(super.initF());
  }
  ff(){
    console.log(super.initF());
  }
}

class C extends B {
  constructor() {
    super();
  }
}

new B().ff();

A.prototype.p = 10;

new C().ff();

Upvotes: 2

Related Questions