JavaScript借用构造函数的继承

JavaScript如何实现继承

  1. 借助call来进行继承

下面展示一些 内联代码片

 	function Parent(name, age) {
      this.name = name;
      this.age= age;
      this.arr = [1, 2, 3]
      this.howold= function () {
        console.log(`我${this.age}岁了!`)
      }
    }
    Parent.prototype.run = function () {//原型对象上的方法
      console.log('I can run fast')
    }
	function Child(name, age color) {
      Parent.call(this, name, size)
      this.color = color
    }
    let child= new Child('小明', 18, '白色')
    console.log(child.name)
    console.log(child.arr)
    child.howold()//我18岁了!
    child.run()//报错  无此方法
通过call方法改变this指向的方式可以继承父构造函数的属性值和方法, 但是继承不到父类原型上面的方法
  1. (结合1)借助原型链实现原型对象上的继承
同样以上面为例
	function Child(name, age color) {
      Parent.call(this, name, size)
      this.color = color
    }
    Child.prototype = new Parent()
    let child= new Child('小明', 18, '白色')
    console.log(child.name)
    child.howold()//我18岁了!
    child.run()//I can run fast
这样便实现对父构造函数原型对象上方法与属性的继承(这就是组合继承)
  1. 组合继承优化
以上组合继承还存在一点问题,就是我们在继承的过程中Parent()构造函数会多执行一次,我们不应该让他执行,解决方法就是直接将构造函数原型赋值给子构造函数。
	function Child(name, age color) {
      Parent.call(this, name, size)
      this.color = color
    }
    Child.prototype = Parent.prototype
    let child= new Child('小明', 18, '白色')
    console.log(child.name)
    child.howold()//我18岁了!
    child.run()//I can run fast
这样看似没有问题,但其实我们直接改变了子构造函数的原型对象同时,也将原型对象的constructor属性直接指向是父类的构造函数  这是不对的
    console.log(Child.prototype.constructor)// Parent()
  1. 组合继承最终版
进一步优化是 要改变子构造函数原型对象上的constructor属性 
或许我们可以直接这样改变将此时的子类 Child.prototype.constructor = Child
但是直接这样修改  也会修改掉父类Parent中的constructor属性  这是不好的

所以我们要通过 子类.prototype=Object.create(父类.prototype)来继承
Object.create会根据现有的对象来提供新创建的对象的__proto__,即做了一层隔离的保护  
再进行 子类.prototype.constructor = 子类构造函数的赋值
	function Child(name, age color) {
      Parent.call(this, name, size)
      this.color = color
    }
    //Child.prototype = Parent.prototype
    Child.prototype =Object.create(Parent.prototype)
    Child.prototype.constructor = Child
    let child= new Child('小明', 18, '白色')
    console.log(child.name)
    child.howold()//我18岁了!
    child.run()//I can run fast
    console.log(Child.prototype.constructor)// Child()

总结

在使用构造函数进行继承的过程中,首先要考虑继承父类本身属性方法的同时还要考虑其原型链上的方法,而在原型链继承的方法中也要考虑到直接改变子类原型对象带来的问题,便是子类原型对象上的constructor指向问题。

所以采用这种借助call和原型链继承的组合继承是实现JavaScript继承的一种方式
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值