ES5与ES6的继承语法

405 阅读1分钟

前言

本文默认读者对于JavaScript原型链面向对象编程OOP有一定的了解

JS中没有类class的概念,也没有继承的概念,这里使用这些术语只是为了方便理解JS面向对象编程的方式

ES5的JS继承模型

//基类
function Animal(name, energy) {
    this.name = name
    this.energy = energy
}

Animal.prototype.eat = function (amount) {
    console.log(`${this.name} is eating.`)
    this.energy += amount
}

Animal.prototype.sleep = function (length) {
    console.log(`${this.name} is sleeping.`)
    this.energy += length
}
Animal.prototype.play = function (length) {
    console.log(`${this.name} is playing.`)
    this.energy -= length
}

//子类
function Dog(name, energy, breed) {
    Animal.call(this, name, energy)
    this.breed = breed	
}
Dog.prototype = Object.create(Animal.prototype) 
Dog.prototype.constructor = Dog 
Dog.prototype.bark = function () {
    console.log('Woof Woof!')
    this.energy -= 1
}

ES5中实现继承的几个关键操作:

  • 子类构造函数中调用父类的构造函数,实现部分属性构造

    Animal.call(this, name, energy)

    操作本质在于:对于子类实例调用父类的构造函数,但是this关键字的指向是子类的实例,而不是父类实例

  • 子类的原型对象指向父类

    Dog.prototype = Object.create(Animal.prototype)

    子类的原型是父类的一个实例对象,因此原型链的查找原则对于子类适用

  • 子类的构造函数指向子类自身的构造函数

    Dog.prototype.constructor = Dog

    由于上面第二步的操作,导致子类原型对象(也就是父类的一个实例对象)的constructor属性是父类的构造函数,因此需要手动将其设置为子类自身原来的构造函数

ES6中原型与继承

ES6中JS可以使用class关键字,但是只是语法糖(syntax sugar)而已,本质上原型链方式并没有改变

//父类
class Animal{
    constructor(name,energy){
        this.name=name
        this.energy=energy
    }
    eat (amount) {
        console.log(`${this.name} is eating.`)
        this.energy += amount
    }
    sleep(length) {
        console.log(`${this.name} is sleeping.`)
        this.energy += length
    }
    play(length) {
        console.log(`${this.name} is playing.`)
        this.energy -= length
    }
}
//子类
class Dog extends Animal{
    constructor(name,energy,breed){
        super(name,energy)
        this.breed=breed
    }
    bark() {
        console.log('Woof Woof!')
        this.energy -= 1
    }    
}

作为JS原语言使用者的一些感想

JavaScript是一门多范式编程语言,可以是 函数式编程面向对象编程面向过程编程...

这里的范式指代编程中的一些原则:

  1. js中函数也是一种数据类型,因此可以实现函数式编程方式
  2. 如同本文讲述的JS继承语法问题,这让JS可以实现面向对象编程的方式

。。。。。。

本质而言,这些都是语法层面上为熟悉OOP编程或者FP编程开发者减少开发时间成本

我个人对JS语言感觉就是,这门语言真的很混乱,从语言标准ES到语言实现JS存在这很大的差距,不仅是语法上的差距,还有实现原理上的差距,幸运的是我们有 babelJS

所以个人看法就是:熟悉JS基本原理 + 学习ES最新语法 + babel转码

有反驳的欢迎来锤