38.JS继承的方式

1.原型链继承

每一个构造函数都有一个原型对象(prototype),原型对象又包含一个指向构造函数的指针,而实例又包含一个指向原型对象的指针(即__proto__),这个连接存在于实例与构造函数的原型对象之间,而不是存在于实例与构造函数之间。如下图,person是Person的实例化对象

function Parent(){
    this.name = 'aDong'
    this.play = [1,2,3]
}
function Child(){
    this.type = 'child'
}
Child.prototype = new Parent();
var s1 = new Child();
var s2 = new Child();
s1.play.push(4)
console.log(s1.play);//[1,2,3,4]
console.log(s2.play);//[1,2,3,4]

s1和s2共用同一个实例对象,内存空间共享

2.构造函数继承

借助call调用Parent构造函数

function Parent(){
    this.name = 'aDong'

}
Parent.prototype.getName = function(){
    return this.name 
}
function Child(){
    Parent.call(this)
    this.type = 'child'
}
var c = new Child()
console.log(c);
console.log(c.getName());//报错

 优化了第一种的继承方式的弊端,但是只能继承父类的属性和方法,不能继承原型属性和方法

3.组合式继承

将前面两种的继承方式结合起来

function Parent(){
    this.name = 'aDong'

}
Parent.prototype.getName = function(){
    return this.name 
}
function Child(){
    Parent.call(this)
    this.type = 'child'
    this.arr = [1,2,3]
}
Child.prototype = new Parent()
var s1 = new Child()
var s2 = new Child()
s1.arr.push(4)

//两个实例之间互不影响
console.log(s1.arr);[1,2,3,4]
console.log(s2.arr);[1,2,3]

console.log(s1.getName());//aDong

4.原型式继承

let Parent = {
    name:'aDong',
    friends:['oyfc','hzg'],
}

let child1 = Object.create(Parent);
child1.friends.push('zmk')
let child2 = Object.create(Parent);

console.log(child1.friends);//['oyfc', 'hzg', 'zmk']
console.log(child2.friends);//['oyfc', 'hzg', 'zmk']

Object.create是浅拷贝,多个实例的引用属性指向同一个内存空间,存在篡改的可能

5.寄生式继承

let Parent = {
    name:'aDong',
    friends:['oyfc','hzg'],
}

function clone(obj){
    let clone = Object.create(obj);
    obj.getFriends = function(){
        return this.friends
    }
    return clone
}

let child1 = clone(Parent)
child1.friends.push('zmk')
let child2 = clone(Parent)

console.log(child1.friends);//['oyfc', 'hzg', 'zmk']
console.log(child2.friends);//['oyfc', 'hzg', 'zmk']
console.log(child1.getFriends());//['oyfc', 'hzg', 'zmk']

利用浅拷贝的性质,再添加一些方法,缺点和原型式继承一样

6.寄生组合式继承

这种继承方式是除class之外最优的继承方式

function clone(parent,child){
    //改用Object.create可以减少组合继承中多进行一次构造的过程
    child.prototype = Object.create(parent.prototype)
    child.prototype.constructor = child
}

function Parent(){
    this.name = 'aDong'
    this.friends = [1,2,3]
}
Parent.prototype.getName = function(){
    return this.name 
}

function Child(){
    Parent.call(this)
    this.name = 'child'
}
clone(Parent,Child)
Child.prototype.getFriends = function(){
    return this.friends
}

let child = new Child();
console.log(child);//Child {name: 'child', friends: Array(3)}
console.log(child.getName());//child
console.log(child.getFriends());//[1,2,3]

7.class继承

ES6新增class关键字,目的是为了消除函数的二义性!

class Parent{
    constructor(){
        this.name = 'aDong'
        this.friends = [1,2,3]
    }
    getName() {
        return this.friends
    }
}
class Child extends Parent{
    constructor(){
        super()
        this.friends = [4,5,6]
    }
    getName(){
        return this.name
    }
    getFriends(){
        return this.friends
    }
}

let child = new Child()
console.log(child.getName());//aDong
console.log(child.getFriends());//[4,5,6]

  • 30
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值