JavaScript 中的继承
🎗️

JavaScript 中的继承

Property
FrontEnd
Year
2021
Author
Tweet

类的声明方式

类的声明方式共有两种
  • 函数
function Animal () { this.name = 'name' }
  • ES6class
class Animal { constructor () { this.name = name } }

类的实例化

使用 new 关键字

类的继承

  1. 借助构造函数实现继承
function Parent() { this.parent = 'parent' } function Child() { Parent.call(this); this.eat = 'eat' } console.log(new Child())
通过使用 callapply方法来改变 this 的指向可实现继承,如上图所示。但是有一个问题是,不能去继承原型链上的方法
function Parent() { this.parent = 'parent' } Parent.prototype.eat = function () {}; function Child() { Parent.call(this); this.eat = 'eat' } console.log(new Child()) console.log(new Child().eat())
notion image
  1. 借助原型链实现继承
function Parent() { this.parent = 'parent' } function Child() { this.eat = 'eat' } Child.prototype = new Parent(); console.log(new Child())
可以看到,将父类的实例赋值到子类的原型对象上,也可实现继承。但是这种会存在一种问题,如下所示
function Parent() { this.parent = 'parent' this.arr = [1, 2, 3] } function Child() { this.eat = 'eat' } Child.prototype = new Parent(); const child1 = new Child(); const child2 = new Child(); child1.arr.push(4) console.log(child1.arr, child2.arr)
一个子类实例对其继承的属性进行修改,则会影响别的实例
  1. 组合继承
function Parent() { this.parent = 'parent' this.arr = [1, 2, 3] } function Child() { Parent.call(this); this.eat = 'eat' } Child.prototype = new Parent(); const child1 = new Child(); const child2 = new Child(); child1.arr.push(4) console.log(child1.arr, child2.arr)
通过组合的方式后就可以实现继承了。但是其中还有两个问题:
  1. 无法判断 child1 是由Child 还是 Parent 直接创建的实例
  1. 父类的构造函数执行了两次,这是没有必要的
所以为了解决这两个问题,有下面的优化版
function Parent() { this.parent = 'parent' this.arr = [1, 2, 3] } function Child() { Parent.call(this); this.eat = 'eat' } Child.prototype = Object.create(Parent.prototype); Child.prototype.constructor = Child; const child1 = new Child(); const child2 = new Child(); const parent1 = new Parent() child1.arr.push(4) console.log(child1.arr, child2.arr) console.log(parent1, child1)
notion image
同时,也可以看出来,parent1 实例的 constructor 指向的是 Parent 构造函数,而 child1 实例的 constructor 指向的是 Child 构造函数
通过 Object.create 创建对象的方式代表的意思就是 Child.prototype.__proto__ = Parent.prototype