概述
类的继承可以通过extends
实现,让子类继承父类的属性和方法,而在子类内部(构造函数constructor)必须调用super()
实现继承(super()
代表父类构造函数,调用之后生成一个继承父类的this
对象)
继承机制
ES6 的继承机制,与 ES5 完全不同:
- ES5 的继承机制,是先创造一个独立的子类的实例对象,然后再将父类的方法添加到这个对象上面,即“实例在前,继承在后”
- ES6 的继承机制,则是先将父类的属性和方法,加到一个空对象上面,然后再将该对象作为子类的实例,即“继承在前,实例在后”
- 所以 ES6 的继承必须先调用
super()
,这样会生成一个继承父类的this
对象,没有这一步就无法继承父类。这意味着新建子类实例时,父类的构造函数必定会先运行一次 super
既可以作为函数使用,也可以作为对象使用,两种方式有很大的不同,详见下文
super
作为函数
super()
作为函数调用时(子内constructor
内部必须调用),代表父类的构造函数,调用之后生成的是子类的实例,即super()
内部this
指向的是子类的实例(由构造函数this
指向可得出,构造函数内部this
指向的是生成的实例,而super()
调用之后生成的是子类实例)
构造函数 this
【首先要明确this
指向】:
- 普通函数:内部的
this
指向函数运行时所在的对象,也即指向函数的直接调用者* 如果一个函数在全局环境运行,this就指向顶层对象(浏览器中为window对象)* 如果一个函数作为某个对象的方法运行,this就指向那个对象;* 如果一个函数作为构造函数,this指向它的实例对象 - 箭头函数:没有自己的
this
对象,内部的this
就是定义时上层作用域中的this
要注意的是,构造函数只能是普通函数,箭头函数不能作为构造函数(没有prototype
),不可以对箭头函数使用new
命令,否则会抛出一个错误
【其次要知道new
操作符做了哪些事情】:
1.创建一个空对象 instance
({}
)
2.将instance
的[[prototype]]
属性指向构造函数fn
的原型(即instance.[[prototype]] = fn.prototype
),也即instance
的__proto__
要指向构造函数的原型prototype
3.执行构造函数,使用 call/apply
改变 this
的指向 => 让this
指向创建出来的实例instance
4.若函数返回值的是对象类型则作为new
方法的返回值返回,否则返回刚才创建的全新对象
function isO