javascript继承的几种方法

继承是面向对象编程中很重要的概念,在其它面向对象的语言中大都很简单,例如java中有关键词extends来实现

javascript语言在ES6也新增了extends关键词可以实现继承,用法与java其实大同小异:

 class Animal {
     constructor(props) {
         this.name = props.name
     }
     eat(){
         console.log(`${this.name} 要吃东西`)
     }
 }    
 class Dog extends Animal {
     constructor(props) {
         //调用实现父类的构造函数
         super(props);
         this.type = props.type
     }
     run(){
         console.log(`${this.name}要跑了`)
     }
 }
 
 const xiaobao = new Dog({name:"xiaobao"})
 console.log(xiaobao.eat(),xiaobao.run())

如果不用class 和extends关键词呢?

要实现继承,那么首先要定义一个被继承的父类:

function Animal(name){
    this.type = "Animal"
    this.array = [1,2,3]
}
Animal.prototype.eat = function(type){
    console.log(this.name +"喜欢吃"+type)
}

1.构造函数

  利用call/apply方法改变函数上下文实现继承,这种办法有很明显的缺点:不能继承父类的原型的属性或方法

function Dog(name){
    Animal.call(this)
    this.type = "dog"
    this.name = name
    
}
var xb = new Dog("小宝")
xb.type // dog
xb.array // [1,2,3]
xb.eat('骨头') // Uncaught TypeError: (intermediate value).eat is not a function

2.原型链

  使子类原型对象指向父类的实例以实现继承,缺点是会共用原型,不能多继承,当有多个实例时数据会共通,这当然不是我们想要的。

function Dog(name){
    this.type="dog"
    this.name = name
}

Dog.prototype = new Animal()

var xb = new Dog("小宝")
var dd = new Dog("点点")

xb.array // [1,2,3]
dd.array // [1,2,3]
xb.array.push(4)

xb.array // [1,2,3,4]
dd.array // [1,2,3,4]

3.组合继承

  调用父类构造函数,再使子类原型对象指向父类的实例,缺点是会调用两次父类构造函数

function Dog(name){
    Animal.call(this)
    this.type="dog"
    this.name = name
}
Dog.prototype = new Parent3()

4.组合继承--优化版

扫描二维码关注公众号,回复: 5374745 查看本文章

  将子类的原型指向父类的原型的对象(将父类的原型用Object.create()处理下,将子父的构造函数隔离开,没有这一步将会造成父类的构造函数被覆盖),再修复constructer,将子类构造函数赋给子类的原型的构造函数。

function Dog(name){
    Animal.call(this)
    this.type="dog"
    this.name = name
}
Dog.prototype = Animal.prototype
Dog.prototype = Object.create(Animal.prototype)
Dog.prototype.constructor = Dog

后面两种方式推荐使用,没有什么明显的缺点。

猜你喜欢

转载自www.cnblogs.com/syll/p/10458799.html