Blog icon indicating copy to clipboard operation
Blog copied to clipboard

原型与原型链 - 实现继承的方式及优缺点

Open logan70 opened this issue 5 years ago • 0 comments

实现继承的方式及优缺点

面向对象编程

面向对象编程(Object Oriented Programming),简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。

面向对象编程的三大基本特性:封装,继承,多态

封装

将一段逻辑/概念抽象出来做到“相对独立”。封装的概念并不是OOP独有的,而是长久以来一直被广泛采用的方法。主要目的总结为两点:

  • 封装数据和实现细节。达到保护私有内容、使用者无需关心内部实现、且内部变化对使用者透明的目的。
  • 封装变化。将不变和可变部分隔离,提升程序稳定性、复用性和可扩展性。

JavaScript中典型的封装就是模块化,实现方法有闭包ES ModuleAMDCMDCommonJS等。

多态

多态的概念也不是OOP独有的。所谓多态就是同一操作作用于不同的对象上面,可以产生不同的解释和不同的执行结果。

多态的目的就是用对象的多态性消除条件分支语句,提升程序的可拓展性。

JavaScript是一门弱类型多态语言,具有与生俱来的多态性。

继承

两大概念:

  • 类(Class):抽象的模板;
  • 实例(Instance):根据类创建的具体对象。

JavaScript中没有类的概念,使用构造函数作为对象模板,通过原型链来实现继承(ES6 中的Class只是语法糖)。

原型及原型链相关知识详见深入JavaScript系列(六):原型与原型链

类式继承

将父类实例赋值给子类原型。缺点如下:

  • 父类实例过早创建,无法接受子类的动态参数;
  • 子类所有实例原型为同一父类实例,修改父类实例属性会影响所有子类实例。
function SupClass() {...}
function SubClass() {...}
SubClass.prototype = new SupClass()

构造函数式继承

子类构造函数中执行父类构造函数。缺点如下:

  • 无法继承父类原型上的属性和方法。
function SupClass() {...}
function SubClass() {
  SupClass.call(this, arguments)
}

组合式继承

类式继承+构造函数继承。缺点如下:

  • 父类构造函数需调用两次。
function SupClass() {...}
function SubClass() {
  SupClass.call(this, arguments)
}
SubClass.prototype = new SupClass()

原型式继承

对类式继承的封装,功能类似Object.create,缺点如下:

  • 若每次传入同一个原型,还是存在修改后影响其他子类实例的问题。
function createObj(o) {
  function F() {}
  F.prototype = o
  return new F()
}

寄生式继承

拓展原型式继承创建的对象并返回。

function createObj(o) {
  const obj = Object.create(o)
  obj.name = 'Logan'
  return obj
}

寄生组合式继承

寄生式继承+构造函数式继承。

function inherit(child, parent) {
  const p = Object.create(parent.prototype)
  child.prototype = p
  p.constructor = child
  return child
}

function SupClass() {...}
function SubClass() {
  SupClass.call(this)
}

SubClass = inherit(SubClass, SupClass)

logan70 avatar Nov 21 '19 08:11 logan70