夜下客

繁体版 简体版
夜下客 > JS修炼法则 > 第9章 继承

第9章 继承

JS 继承(委托更恰当)

引子: 上一篇文章中谈到了,原型的作用之一是实现继承。那么这篇文章会围绕继承来展开。 思路:继承一词真的恰当吗?何谓继承,何谓委托?有多少种方式实现继承?这些实现方式的演变如何去记忆?ES6 的 extends 关键字是用哪种继承方式实现的呢? JavaScript 是基于原型实现面向对象的,在 JS 中,面向对象概念中的继承是基于原型的。

常见的 JS 继承有 7 种方式:原型链继承和借用构造函数继承,二者结合诞生了组合继承;基于原型链继承和借用构造函数继承而衍生的 原型式继承和寄生式继承,二者结合诞生了最理想的寄生组合式继承。以及最后一种 ES6 的方式,class 语法糖。

0. 前言

定义

继承是类与类之间的关系。JS基于原型进行继承。

作用

使得子类具有父类的各种属性和方法。

1.原型链继承

function Parent() {}

function Child() {}

Child.prototype = new Parent()

优点:简单

缺点:1.属性被实例共享 2.不能向父类传递参数

2. 借用构造函数(经典继承)

function Parent(name) {}

function Child() {

Parent.call(this, name)

优点:1.避免了共享 2.可以向父类传参 缺点:方法在构造函数中定义,创建实例都会创建一遍方法.

3. 组合继承

function Parent() {}

function Child() {

Parent.call(this)

Child.prototype = new Parent()

Child.prototype.constructor = Child

优点:有 1、2 优点,最常用

缺点:调用了两次父亲构造函数

4. 原型式继承( 模拟 Object.create() )

function CreateObj(o) {

function F() {}

F.prototype = o

return new F()

优点:简单

缺点:属性被实例共享

5. 寄生式继承

function createObj(o) {

var clone = Object.create(o)

clone.sayName = function () {}

return clone

优点:简单 缺点:方法在构造函数中定义,创建实例都会创建一遍方法.

6.寄生组合式继承(最理想)

function Parent() {}

function Child() {

Parent.call(this)

var F = function () {}

F.prototype = Parent.prototype

Child.prototype = new F()

优点:1.高效率,只调用一次父构造函数 2.原型链不变

7. class ES6

ES6的class语法糖使用extends实现继承,其底层逻辑是利用寄生组合式继承。

利用网址 Traceur,Google公司出品 将ES6语法转为ES5,如下图所示:

上面图片中的ES6源码如下:

class Animal {

constructor(props, name) {

this.name = name

say() {

console.log('w

『加入书签,方便阅读』