class A {
p(){
return 2;//ES5规定,实例的属性除非定义到this,否则都是定义到了原型上
}
}
class B extends A{
constructor() {
super();
console.log(super.p());//相当于调用父类的原型属性:A.prototype.p()
}
}
let b = new B();
上述代码中,子类B中的super.p()就是将super当做对象使用。那么应该指向父类的原型,也就是A.prototype.p()。
class A {
p(){
this.p = 333;
}
}
class B extends A{
constructor() {
super();
console.log(super.p());// undefined this无法指向实例
}
}
let b = new B();
由于super指向父类的原型对象,所以定义在父类this实例上的方法或属性是无法通过super调用的。
class A {
p(){
this.p = 333;
}
}
//等同于
class A{}
A.prototype.p = 333
迷惑点来了:ES6规定,通过super调用父类的方法时,super会绑定子类的this。
class A {
constructor() {
this.x = 1;
}
print(){
console.log(this.x);
}
}
class B extends A{
constructor() {
super();
this.x = 2;
}
m() {
super.print();// 相当于 super.print.call(this);
console.log(this);//此时的this指向子类B。B {x: 2}
}
}
let b = new B();
b.m();//2
加深印象,通过super调用父类方法时,super会绑定子类的this:
class A {}
class B extends A{
constructor() {
super();
console.log(super.valueOf() instanceof B);// true
}
}
let b = new B();
super.valueOf()表面super是一个对象,所以super绑定B的this,所以super.valueOf()返回的是一个B的实例。
var obj = {
toString(){
return "MyObject:" + super.toString();
}
}
console.log(obj.toString());//MyObject[object object]
由于对象总是继承其他对象的,所以可以在任意一个对象中使用super关键字。