天天看点

聊聊曾经继承那些坑

原型继承和 Class 继承

原型如何实现继承? Class 如何实现继承? Class 本质是什么?

⾸先先来讲下 class ,其实在 JS 中并不存在类, class 只是语法糖,本质还是函数

原型

继承得靠原型来实现,

其实原型的概念很简单:

所有对象都有一个属性

__proto__

指向一个对象,也就是原型

每个对象的原型都可以通过 constructor 找到构造函数,构造函数也可以通过 prototype 找到原型

所有函数都可以通过

__proto__

找到

Function

对象

所有对象都可以通过

__proto__

找到

Object

对象

对象之间通过

__proto__

连接起来,这样称之为原型链。当前对象上不存在的属性可以通过原型链一层层往上查找,直到顶层

Object

对象

其实原型中最重要的内容就是这些了。

class Person {}
Person instanceof Function // true
           

组合继承

组合继承是最常⽤的继承⽅式

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() // 1
child 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() // 1
child instanceof Parent // true
           

以上继承实现的核⼼就是将⽗类的原型赋值给了⼦类,并且将构造函数设置为 ⼦类,这样既解决了⽆⽤的⽗类属性问题,还能正确的找到⼦类的构造函数。

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() // 1
child instanceof Parent // true
           

class 实现继承的核⼼在于使⽤ extends 表明继承⾃哪个⽗类,并且在⼦ 类构造函数中必须调⽤ super ,因为这段代码可以看成

Parent.call(this, value) 。

每天一句中文式外语

泰语

警察署/sha-tan-ni-dan-luo沙潭尼丹摞/ Police Station

医院/long-pa-ya-ban隆帕雅般/Hospital

洗手间/hong-nan哄南/Toilet/W.C

不要/mai-ao卖凹/Don’t/No

要/ao 凹/Need To

不是/mai-cai卖菜/an’t/No

是/cai菜/Is/Yes

不要怕/mai–dong-gua卖冬瓜/Be fearless of

别担心!/mai-dong-huan 卖冬缓/ Care Nothing For!

兄|姐(泰国礼貌称呼)/pi 屁/Elder brother|sister