Class 的继承
class Point {
}
class ColorPoint extends Point {
}
子类必须先在 constructor
方法中调用 super
方法,然后才能用 this
关键字,否则子类就得不到 this
对象。super
方法只能在 constructor
中调用,否则报错。
如果子类没有定义 constructor
也不会报错,会隐式获得一个 constructor
:
class ColorPoint extends Point {
}
// 等同于
class ColorPoint extends Point {
constructor(...args) {
super(...args);
}
}
子类的实例对象既是子类也是父类,这和 ES5 行为一致。
Object.getPrototypeOf
可以用来获得子类的父类。
super
不能单独使用,即 console.log(super)
会报错。这是因为 JavaScript 无法解析是作为函数还是对象使用。
类里面 super
指向的是父类原型对象,可以在子类任何方法里使用。记住,不能通过 super
访问父类定义的属性,除非是原型上的属性。
在子类方法里通过 super
调用父类方法,调用者 this
为子类实例。
super
也可以用在静态方法里,指向的是父类(函数)。同样,调用者 this
为子类(函数)。
__proto__
和 prototype
属性
每一个对象都有 __proto__
属性,指向其构造函数的 prototype
属性。这是为了能让对象使用原型方法。
在继承中,子类原型对象会有个 __proto__
属性指向父类原型。
class Father {}
class Child extends Father {}
Child.__proto__ === Father // true
new Child().__proto__ === Child.prototype // true
// Child 的原型是个 Father 实例
Child.prototype instanceof Father // true
Child.prototype.__proto__ === Father.prototype // true
有点等价于:
class Father {}
class Child {}
Object.setPrototypeOf(Child.prototype, Father.prototype);
Object.setPrototypeOf
的实现为:
Object.setPrototypeOf = function (obj, proto) {
obj.__proto__ = proto;
return obj;
}
如果没有明确继承,则自动继承 Object
类:
class Hello {}
Hello.__proto__ === Funtion.prototype // true
Hello.prototype.__proto__ === Object.prototype // true