/*
20.3 super 关键字
super 这个关键字既可以当作函数使用,也可以当作对象使用。在这两种情况下,它的用法完全不同。
第一种情况,super 作为函数调用时代表父类的构造函数。es6 要求,子类的构造函数必须执行一次 super 函数。
作为函数时,super() 只能用在子类的构造函数之中,用在其他地方就会报错
*/
class A {}
class B extends A {
constructor() {
super()
}
}
/*
上面的代码中,子类 B 的构造函数中 super() 代表调用父类的构造函数。这是必须的,否则 js 引擎会报错
super 虽然代表了父类 A 的构造函数,但是返回的是子类 B 的实例,
即 super 内部的 this 指的是 B,
因此 super() 在这里相当于 A。prototype.constructor.call(this)
*/
class A2 {
constructor() {
console.log(new.target)
console.log(new.target.name)
}
}
class B2 extends A2 {
constructor() {
super()
}
}
var a = new A2()
var b = new B2()
console.log(a)
console.log(b)
/*
第二种情况,super 作为对象时在普通方法中指向父类的原型对象;在静态方法中指向父类
*/
/*
20.4 类的 prototype 属性和 __proto__ 属性
在大多数浏览器的 es5 实现之中,每一个对象都有 __proto__ 属性,指向对应的构造函数的 prototype 属性。
class 作为构造函数的语法糖,同时有 prototype 属性和 __proto__ 属性,因此同时存在两条继承链。
+ 子类的 __proto__ 属性表示构造函数的继承,总是指向父类。
+ 子类 prototype 属性的 __proto__ 属性表示方法的继承,总是指向父类的 prototype 属性
*/
class AA {
}
class BB extends AA {
}
BB.__proto__ === AA // true
BB.prototype.__proto__ === AA.prototype // true
// 上面的代码中,子类 BB 的 __proto__ 属性指向父类 AA,子类 BB 的 prototype 属性的 __proto__ 属性指向父类 AA 的 prototype 属性