ES5 是通过修改原型链实现继承, ES6 class 通过 extends 关键字实现.
class Point {
}
class ColorPoint extends Point {
constructor() {
super()
}
}
子类必须在 constructor 方法中调用 super 方法,否则新建实例时会报错。这是因为子类自己的 this 对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用 super 方法,子类就得不到 this 对象。
在子类的构造函数中,只有调用super之后,才可以使用this关键字,否则会报错。
class A {
static hello() {
console.log('hello world');
}
}
class B extends A {
}
B.hello() // hello world
静态方法也会被继承到子类上
Object.getPrototypeOf(ColorPoint) === Point
可以使用 Object.getPrototypeOf 来判断一个类是否继承了另一个类
lass A {
constructor() {
this.x = 1;
}
}
class B extends A {
constructor() {
super();
this.x = 2;
super.x = 3;
console.log(super.x); // undefined
console.log(this.x); // 3
}
}
let b = new B();
上面代码中,super.x 赋值为3,这时等同于对 this.x 赋值为3。而当读取 super.x 的时候,读的是 A.prototype.x ,所以返回undefined。
class Parent {
static myMethod(msg) {
console.log('static', msg);
}
myMethod(msg) {
console.log('instance', msg);
}
}
class Child extends Parent {
static myMethod(msg) {
super.myMethod(msg);
}
myMethod(msg) {
super.myMethod(msg);
}
}
Child.myMethod(1); // static 1
var child = new Child();
child.myMethod(2); // instance 2
如果super作为对象,用在静态方法之中,这时super将指向父类,而不是父类的原型对象。
首先明确一件事情, 对象都有所谓的原型, 也就是 obj.proto (原型). 永远指向构造函数的 prototype (原型对象).
对于类而言, 类是一类语法糖, 所以很直觉的就是它既有 proto 和 prototype