JS继承的几种方式

继承

很多面向对象的语言都支持两种继承:接口继承和实现继承。前者知识继承方法签名,后者继承实际的方法。接口继承在ECMAScript中是不可能的,因为函数没有签名。实现继承是ECMAScript唯一支持的继承方式,主要通过原型链实现的

原型链继承

重温一下构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型有一个属性constructor属性指回构造函数,而实例有一个内部指针指向原型,如果原型是另一个类型的实例呢?那就意味着这个原型本身有一个内部指针指向另一个原型,相应的另一个原型也有一个指针指向另一个构造函数。这样就在实例和原型之间构造了一条原型链
实现原型链继承代码

<script>
//被继承的函数
  	function Super () {
        this.like = {
            1:"play",
            2:"read"
        }
        this.name = 123
    }
    //往super原型中添加方法
    Super.prototype.getName = function () {
        console.log(this.name)
    }
  	function Sub () {
        	
    }
    //通过原型链实现继承
    //Sub的显式原型指向Super的实例,即可以通过原型链访问到Super原型中的方法
     Sub.prototype = new Super()
     var a = new Sub()
     console.log(a.getName) //funcition
</script>

原型链继承也有问题,问题出现在原型中包含引用值的时候。原型中包含的引用值会在所有实例间共享
例子

<script>
  	function Super () {
        this.like = ['red','yellow','black']
    }
      function Sub () {
      
    }
    Sub.prototype = new Super()
    var a = new Sub()
    a.like.unshift('green')
    var c = new Sub()
    //尽管c中没有添加green,但c中还是有green,因为引种值在实例中共享
    console.log(a.like,c.like) 
</script>

盗用构造函数

为了解决原型包含引用值导致继承问题,盗用构造函数流行起来,基本思路很简单,在子类构造函数中调用父类构造函数
例子

<script>
  	function Super () {
        this.like = ['red','yellow','black']
        this.name = 123
    }
    function Sub () {
        Super.call(this)
    }
    Sub.prototype = new Super()
    var a = new Sub()
    a.like.unshift('green')
    var c = new Sub()
    //此时a和c的输出就不是相同的了
    console.log(a.like,c.like)
</script>

通过使用call()或者apply()方法,Super构造函数在为Sub的实例创建新的对象的上下文中执行了。想到与Sub对象上运行了Super函数中所有初始化代码,结果就是每个实例会有自己的属性

组合继承

将上面两者优点集中了起来,基本思路使用原型链上的属性和方法,而通过盗用构造函数来继承实例属性。

<script>
 function Super () {
        this.like = ['red','yellow','black']
        this.name = 123
    }
    Super.prototype.getName = function () {
        console.log(this.name)
    }
    function Sub () {
        Super.call(this)
    }
    Sub.prototype = new Super()
    var a = new Sub()
    a.like.unshift('green')
    var c = new Sub()
    a.name = 456
    console.log(a.like,c.like)
    console.log('--------')
    console.log(a.name,c.name)
    console.log('--------')
    console.log(a.getName,c.getName)
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值