1.class可以通过extends关键字实现继承,比es5的通过修改原型链实现继承,要清晰和方便。
子类必须在constructor方法中调用super方法,否则新建实例时会报错
对比:
ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。ES6 的继承机制完全不同,实质是先创造父类的实例对象this(所以必须先调用super方法),然后再用子类的构造函数修改this
在子类的构造函数中,只有调用super之后,才可以使用this关键字,否则会报错
2.Object.getPrototypeOf()方法可以用来从子类上获取父类。
Object.getPrototypeOf(ColorPoint) === Point// true
可以使用这个方法判断,一个类是否继承了另一个类。
3.super关键字
super既可以当做函数使用,也可以当做对象使用。
1>作为函数调用时,代表父类的构造函数。(Es6要求:子类的构造函数必须执行一次super函数。)
class A{}
class B extends A {
constructor(){
super();
}
}
子类B的构造函数之中的super(),代表调用父类的构造函数
注意,super虽然代表了父类A的构造函数,但是返回的是子类B的实例,即super内部的this指的是B,因此super()在这里相当于A.prototype.constructor.call(this)
class A {
constructor() {
console.log(new.target.name);
}
}
class B extends A {
constructor() {
super();
}
}
new A() // A
new B() // B
new.target指向当前正在执行的函数
super()内部的this指向的是B
当作为函数时,super()只能用在子类的构造函数之中,用在其他地方就会报错
2>第二种情况,super作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类。
属性定义在父类的原型对象上,super就可以取到
ES6 规定,通过super调用父类的方法时,super会绑定子类的this
使用super的时候,必须显式指定是作为函数、还是作为对象使用,否则会报错
4.类的 prototype 属性和proto属性
大多数浏览器的 ES5 实现之中,每一个对象都有proto属性,指向对应的构造函数的prototype属性。Class 作为构造函数的语法糖,同时有prototype属性和proto属性,因此同时存在两条继承链。
(1)子类的proto属性,表示构造函数的继承,总是指向父类。
(2)子类prototype属性的proto属性,表示方法的继承,总是指向父类的prototype属性。
extends 的继承目标
extends关键字后面可以跟多种类型的值。
extends 的继承目标
extends关键字后面可以跟多种类型的值。
class B extends A {
}
代码的A,只要是一个有prototype属性的函数,就能被B继承。由于函数都有prototype属性(除了Function.prototype函数),因此A可以是任意函数
三种特殊情况:
1>子类继承Object类
2>不存在任何继承
3>子类继承null
实例的 proto 属性
子类实例的proto属性的proto属性,指向父类实例的proto属性。也就是说,子类的原型的原型,是父类的原型
5.原生构造函数的继承
原生构造函数是指语言内置的构造函数,通常用来生成数据结构。ECMAScript 的原生构造函数大致有下面这些。
Boolean()
Number()
String()
Array()
Date()
Function()
RegExp()
Error()
Object()
以前,这些原生构造函数是无法继承的,比如,不能自己定义一个Array的子类
6.Mixin 模式的实现
Mixin 模式指的是,将多个类的接口“混入”(mix in)另一个类