ES5、ES6的四种继承方法

社会主义新天地 提交于 2020-01-27 14:58:19

ES5、ES6的四种继承

众所周知,在ES6之前,前端是不存在类的语法糖,所以不能像其他语言一样,使用extends关键字就搞定继承关系,需要一些额外的方法来实现继承。

一. 原型链继承

function Parent(){
    this.name = 'mortal'
}
Parent.prototype.getName = function(){
    console.log(this.name)
}
function child(){
    
}
//主要精髓所在
Child.prototype = new Parent()
Child.prototype.constructor = Child

let mortalChild = new Child()
mortalChild.getName()  //'mortal'

原型链继承缺点:
1.每个实例对引用类型属性的修改都会被其他的实例共享。

function Parent(){
    this.names = ['mortal','mortal1']
}
function Child(){
    
}
//主要精髓所在
Child.prototype = new Parent()
Child.prototype.constructor = Child

let mortalChild2 = new Child()
mortalChild2.name.push('mortal2')
console.log(mortalChild2.names) //['mortal','mortal1','mortal2']

let mortalChild3 = new Child()
mortalChild3.name.push('mortal3')
console.log(mortalChild3.names) //['mortal','mortal1','mortal2','mortal3']

2.在创建Child实例的时候,无法向Parent传参。这样就会使Child实例没法自定义自己的属性(名字)

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

function Parent(){
    this.names = ['mortal','mortal1']
}
function Child(){
    Parent.call(this)
}
let mortalChild2 = new Child()
mortalChild2.names.push('mortal2')
console.log(mortalChild.names) //['mortal','mortal1','mortal2']

let mortalChild3 = new Child()
mortalChild3.names.push('mortal3')
console.log(mortalChild3.names) //['mortal','mortal1','mortal3']

优点:
1.解决了每个实例对引用类型属性的修改都会被其他的实例共享的问题。
2.子类可以向父类传值。

function Parent(name){
    this.name = name
}
function Child(name){
    Parent.call(this,name)
}

let mortalChild = new Child('mortal')
console.log(mortalChild.name)  //mortal

let mortal2Child = new Child('mortal2')
console.log(mortal2Child.name) //mortal2

缺点:
1.无法复用父类的公共函数
2.每次子类构造实例都得执行一次父类函数。

三. 原型式继承

复制传入的对象到创建对象的原型上,从而实现继承

function createObj(o){
    function F(){}
    F.prototype = o
    return new F()
}
let person = {
    name:'mortal'
    body:['foot','hand']
}

let person1 = createObj(person)
let person2 = createObje('person')

console.log(person1)  //mortal
person1.body.push('head')
console.log(person2)  //['foot','hand','head']

缺点:同原型链继承一样,每个实例对引用类型属性的修改都会被其他的实例共享

ES6继承

ES6支持通过类来实现继承,方法比较简单,代码如下:

class Point{
    constructor(x,y){
        this.x = x
        this.y = y
    }
    
    toString(){
        return this.x + '' + this.y
    }
}
class ColorPoint extends Point{
    constructor(x,y,color){
        super(x,y)  //调用父类的constructor(x,y)
        this.color = color
    }
    toString(){
        return this.color + ' ' + super.toString() //调用父类的toString()
    }
}
let colorPoint = new ColorPoint('1','2','red')
console.log(colorPoint.toString()) //red 12


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!