在上篇文章主要讲了Class的相关介绍,
这篇文章来讲讲Class继承的相关概念吧。
先抛出一个关键字:extends
在ES6中,不需要修改原型链来实现继承,通过extends关键字实现继承,要清晰和方便的多。
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
class ColorPoint extends Point {
constructor(x, y, color) {
super(x, y);
this.color = color; // 正确
}
}
这里有几个注意点
Tips:
1:子类必须在constructor方法中调用super方法,否则新建实例时会报错。
2:在构造函数中,只有调用了super()(父类的构造函数)之后,才可以调用this关键字。
3:父类的静态方法,子类也会继承
4:不管子类有没有编写constructor方法,这个方法都会默认添加
这里分析一下原因吧:
子类的this对象,必须先通过父类的构造函数完成塑造,
在得到与父类同样的是实例属性和方法,然后再对其加工,
加上子类自己的实例属性和方法。
如果不调用,子类就无法获取this,自然会报错了
Object.getPrototypeOf()
Object.getPrototypeOf方法可以用来从子类上获取父类。
Object.getPrototypeOf(ColorPoint) === Point
// true
可以使用这个方法判断,一个类是否继承了另一个类。
值得注意的是,这里只能获取的是父类,祖先类就不能这么判断了。
super关键字
super的使用有两种情况:
1:super作为函数调用时,代表父类的构造函数。
2:作为对象时,在普通方法中,指向父类的原型对象,在静态方法中指向父类。
第一种情况注意点:
1:super虽然代表父类A的构造函数,但是返回的是子类的实例,(这里在上面有讲)。
这里可以理解成:super()可以当作A.prototype.constructor.call(this)
2:super()只能在constructor调用,可很好理解,一个子类,不可以造出另一个父类吧
第二种情况注意点:
1:super指向的是父类的原型对象,所以定义在父类实例上的属性或方法,是无法通过super获取的。
2:在子类普通方法中通过super调用父类的方法时,方法内部的this指向当前子类实例。
不过这里有个疑惑点:
一个对象默认的getter函数是怎么样的呢?
如果说getter函数里面return this.xxx,那就很奇怪了
因为,我们通过super去赋值时,由于this指向当前子类实例,所以改的是子类的实例的变量
可是如果getter函数里面是return this.xxx的话,就不应该返回父类原型上的变量的值了
可实际上,就是返回父类原型上的变量的值
3:super必须指定为函数或者是对象调用。
类的prototype属性和__proto__属性
1:子类的__proto__属性,表示构造函数的继承,总是指向父类。
2:子类prototype属性的__proto__属性,表示方法的继承,总是指向父类的prototype属性。