> 自媒体
原型链继承和class继承的区别(class继承方法)
导语:原型如何实现继承?Class 如何实现继承?Class 本质是什么?
问题:原型如何实现继承?Class 如何实现继承?Class 本质是什么?
首先先来讲下class,其实在 JS 中并不存在类,class只是语法糖,本质还是函数。
class Person { }Person instanceof Function // true
使用原型和class的方式来实现继承
组合继承
组合继承是最常用的继承方式,
function Parent(value) { this.val = value}Parent.prototype.getValue = function() { console.log(this.val)}function Child(value) { Parent.call(this, value)}Child.prototype = new Parent()const child = new Child(1)child.getValue() // 1child instanceof Parent // true
以上继承的方式核心是在子类的构造函数中通过Parent.call(this)继承父类的属性,然后改变子类的原型为new Parent()来继承父类的函数。
这种继承方式优点在于构造函数可以传参,不会与父类引用属性共享,可以复用父类的函数,但是也存在一个缺点就是在继承父类函数的时候调用了父类构造函数,导致子类的原型上多了不需要的父类属性,存在内存上的浪费。
寄生组合继承
这种继承方式对组合继承进行了优化,组合继承缺点在于继承父类函数时调用了构造函数,我们只需要优化掉这点就行了。
function Parent(value) { this.val = value}Parent.prototype.getValue = function() { console.log(this.val)}function Child(value) { Parent.call(this, value)}Child.prototype = Object.create(Parent.prototype, { constructor: { value: Child, enumerable: false, writable: true, configurable: true }})const child = new Child(1)child.getValue() // 1child instanceof Parent // true
以上继承实现的核心就是将父类的原型赋值给了子类,并且将构造函数设置为子类,这样既解决了无用的父类属性问题,还能正确的找到子类的构造函数。
没有了val:undefined.
// 如果觉得复杂,可以直接两句Child.prototype = Object.create(Parent.prototype)Child.prototype.constructor = Parent.prototype.constructor
Class 继承
以上两种继承方式都是通过原型去解决的,在 ES6 中,我们可以使用class去实现继承,并且实现起来很简单
class Parent { constructor(value) { this.val = value } getValue() { console.log(this.val) }}class Child extends Parent { constructor(value) { super(value) this.val = value }}let child = new Child(1)child.getValue() // 1child instanceof Parent // true
class实现继承的核心在于使用extends表明继承自哪个父类,并且在子类构造函数中必须调用super,因为这段代码可以看成Parent.call(this, value)。
在 JS 中并不存在类,class的本质就是函数,模拟类。
本文内容由小岑整理编辑!