最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 总结JavaScript几种继承的方式及优缺点

    正文概述 掘金(阿畅_)   2021-02-01   602

    1. 原型继承

    原型继承是比较常见一种继承方式

    function Parent() {
      this.name = 'parent'
      this.action = function () {
        console.log(this.name)
        return this.name
      },
      this.arr = [1,2]
    }
    
    Parent.prototype.getName = function () {
      console.log(this.name)
      return this.name
    }
    
    function Child() {
      this.name = 'child'
    }
    // 实例化父函数,链接到自己的原型链上
    Child.prototype = new Parent
    const child1 = new Child
    console.log(child1)
    

    总结JavaScript几种继承的方式及优缺点

    从上图中可以看到, 原型继承的特点:把父类的公有(prototype)+私有属性都继承到了子类的原型上(公有属性 prototype)

    注意:原型继承的缺点

      const child2 = new Child
      console.log(child1)
      child2.arr.push(3)
    

    如果有一个子类 child2 调用 父类的 arr 属性并添加了内容 此时来看 child1 和 child2 总结JavaScript几种继承的方式及优缺点 从上面的结果中发现,child2 修改了父类的属性,child1 的父类属性也被修改了。这也很好理解,因为它俩都继承与同一个 parent。它们的内存空间是共享的。 所以:原型的缺点:子类会共享父类的的内存空间

    构造函数继承(借用 call 或 apply)

    function Parent() {
          this.name = 'parent'
          this.action = function () {
            console.log(this.name)
            return this.name
          },
          this.arr = [1,2]
        }
    
        Parent.prototype.getName = function () {
          console.log(this.name)
          return this.name
        }
    

    总结JavaScript几种继承的方式及优缺点 使用这种解决了数据共享的问题 但是: 只能继承父类的实例属性和方法,不能继承原型属性或者方法。

    组合继承 (call + prototype)

    function Parent() {
      this.name = 'parent'
      this.action = function () {
        console.log(this.name)
        return this.name
      },
      this.arr = [1,2]
    }
    Parent.prototype.getName = function () {
      console.log(this.name)
      return this.name
    }
    
    function Child() {
      this.name = 'child'
      Parent.call(this)
    }
    Child.prototype = new Parent
    Child.prototype.constructor = Child
    const child1 = new Child
    console.log(child1)
    

    总结JavaScript几种继承的方式及优缺点

    优点:解决了 原型继承和构造函数继承的缺点。 但是这种方式也有缺陷:从上图中可以看出,子类原型上多了一份父类的实例属性。因为父类的构造函数被调用了两次,生成了两份,子类实例上的屏蔽了原型上的,造成了内存浪费

    寄生式继承 (Object.create)

    就是使用原型继承获取一份浅拷贝对象。然后利用这个浅拷贝对象在进行增强。 缺点和原型继承一样,但对于普通对象的继承来说,可以在父类的基础上添加更多的方法

    let Parent1 = {
      arr: ['a', 'b'],
      name: 'Parent1',
      getName: function() {
        return this.name
      }
    }
    function Child(parent) {
      let copy = Object.create(parent)
      console.log(copy)
      copy.getArray = function () {
        return this.arr
      }
      return copy
    }
    
    let Child1 = Child(Parent1)
    console.log(Child(Parent1))
    console.log('child1 -->', Child1.getArray()) // ['a', 'b']
    console.log('child1 -->', Child1.getName()) // Parent1
    
    • 缺点 不能实例化,也没有用到原型。

    寄生组合式继承

    function Parent() {
      this.name = 'parent'
      this.action = function () {
        return this.name
      },
      this.arr = [1,2]
    }
    
    Parent.prototype.getName = function () {
      return this.name
    }
    
    function Child() {
      Parent.call(this)
    }
    Child.prototype = Object.create(Parent.prototype)
    Child.prototype.constructor = Child
    
    const child1 = new Child
    const child2 = new Child
    console.log(child1)
    
    • 解决了上面几种几种的缺陷,也较好的实现了继承的结果即 父类私有属性放放子类私有中,原型上的属性和方法放到子类原型上

    注意:上面写的继承中,为什么要手动修改 constructor 的指向 因为:在 JS 的规定中,xxx.prototype.constructor 的指向是当前函数(类)本身。也就是指向自己,我们上面用到的寄生继承、组合继承等,如果不修改 constructor 的指向,它会指向 Parent 这个类, 如下:

    // Child.prototype.constructor = Child
     console.log('constructor -->', Child.prototype.constructor === Parent) // true 
    

    去掉手动指向,Child 的 constructor 就指向了 Parent,所以违背了 JS 的标准规范。

    ES6 extends 关键字

    在 ES6 中,直接使用 extends 关键字可以很容易的实现 JavaScript 继承,并且 babel 编辑之后,它采用的也是 寄生组合继承的方式,这种方式是较优的解决继承的方式。

    class Parent2 {
      constructor(name) {
        this.name = name
      }
      getName = function (){
        return this.name
      }
    }
    class Child2 extends Parent2 {
      constructor(name, age) {
        super(name)
        this.age = age
      }
    }
    const child3 = new Child2('parent', 22)
    const child4 = new Child2('parent1', 25)
    console.log(child3.getName())
    console.log(child3)
    console.log(child4)
    

    总结JavaScript几种继承的方式及优缺点


    起源地下载网 » 总结JavaScript几种继承的方式及优缺点

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元