最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 继承 | 8月更文挑战

    正文概述 掘金(瑾行)   2021-08-19   478

    这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战

    前言

    想必,点进来的都是随时可以继承家产,上班只是为了享受生活,随时能回去躺平的大佬。好,收回正题,毕竟还要靠代码维持生计。

    继承 | 8月更文挑战

    继承是面向对象编程中讨论最多的话题,但却是日常业务开发中极易被忽略的一块内容。
    本文围绕《Javascript高级程序设计第4版》面试高频问题进行知识点梳理。

    原型链继承

    基本思想: 函数Child没有使用默认显式原型,而是替换成函数Parent的实例。使Parent的实例可访问的属性和方法同样存在在函数Child实例的原型链上,从而实现了继承。

    function Parent() {
      this.isRich = true
    }
    Parent.prototype.getIsRich = function() {
      console.log('能回去继承家产么?', this.isRich)
    }
    function Child() {
      
    }
    Child.prototype = new Parent()
    let child1 = new Child('')
    console.log(child1.getIsRich()) // 能回去继承家产么? true
    

    Child函数成功继承了函数Parent的属性,child1可以实现继承家产,不用在外打工。
    问题:原型上引用类型被所有实例共享。

    function Parent() {
      this.banCreditCard = []
      this.isRich = true
    }
    Parent.prototype.getBanCreditCard = function() {
      console.log(this.banCreditCard)
    }
    function Child() {}
    Child.prototype = new Parent()
    let child1 = new Child()
    let child2 = new Child()
    child1.banCreditCard.push('建设银行')
    child2.getBanCreditCard() // 建设银行
    

    child1child2共同拥有parent一起给与的消费信用卡,但当child1建设银行信用卡消费超限额了,导致child2也不能使用该信用卡继续消费。

    构造函数继承

    基本思想Child函数执行Parent函数,将当前函数执行上下文this指向child实例。

    function Parent(name) {
      this.name = name
      this.isRich = true
      this.banCreditCard = []
      this.getBanCreditCard = function() {
        console.log(this.banCreditCard)
      }
    }
    Parent.prototype.getIsRich = function() {
      console.log('能回去继承家产么?', this.isRich)
    }
    function Child(name) {
      Parent.call(this, name)
    }
    let child1 = new Child('瑾行')
    let child2 = new Child('七金')
    child1.banCreditCard.push('建设银行')
    child2.getBanCreditCard() // []
    child1.getRich() // child1.getRich is not a function
    child2.getRich() // child2.getRich is not a function
    

    parent为了减少家庭内部矛盾?,单独给child1child2创办信用卡,这就不会造成child1信用卡限额导致child2不能继续消费的问题。解决了原型链继承引用类型共享的问题,且可传参。
    问题:每创建一个实例都会创建一遍方法,且Parent原型链上的方法无法继承。相当于每个child都得去记住自己信用卡的联系方式去确认信用卡是否停用,很麻烦。

    组合继承

    基本思想:方法使用原型链继承,属性使用构造函数继承

    function Parent(name) {
      this.name = name
      this.isRich = true
      this.banCreditCard = []
    }
    Parent.prototype.getBanCreditCard = function() {
      console.log(this.banCreditCard)
    }
    Parent.prototype.getRich = function() {
      console.log('能回去继承家产么?', this.isRich)
    }
    
    Child.prototype = new Parent()
    Child.prototype.constructor = Child
    function Child(name) {
      Parent.call(this, name)
    }
    
    let child1 = new Child('瑾行')
    let child2 = new Child('七金')
    child1.banCreditCard.push('建设银行')
    child2.getBanCreditCard() // []
    child1.getRich() // 能回去继承家产么? true
    child2.getRich() // 能回去继承家产么? true
    

    解决了引用属性共享问题,且避免方法被重复创建的问题。相当于child1child2能各自使用自己信用卡的同时,又能使用同样的方法(手机号)去联系确认信用卡是否停用。
    问题:基本问题解决了,但不难发现,我们会调用两次Parent构造函数,就是创建Child的原型的时候和创建实例的时候,还有待优化。

    原型式继承

    基本思想:使用Object.create的对parent参数对象浅复制,达到继承parent中的属性和方法。

    Object.create的原生实现,将传入的对象作为创建对象的隐式原型。

    function objectCreate(o) {
      function F(){}
      F.prototype = o
      return new F()
    }
    

    原型式继承思想代码基本实现如下。

    let parent = {
      name: '爸爸',
      isRich: true,
      banCreditCard: []
    }
    let child1 = Object.create(parent)
    let child2 = Object.create(parent)
    child1.name = '瑾行'
    child2.name = '七金'
    child2.banCreditCard.push('建设银行')
    console.log(child1.name) // 瑾行
    console.log(child2.name) // 七金
    console.log(child1.banCreditCard) // ['建设银行']
    

    问题:引用属性会被实例共享,无法传递参数,具备与原型链继承一样的问题。

    寄生式继承

    基本思想:在原型式继承上增强浅复制能力,创建一个用于继承方法的函数。

    function objectCreateEnhance(o) {
      let clone = Object.create(o)
      clone.say = function() {
        console.log('hello world')
      }
      return clone
    }
    

    问题:没有解决引用属性的问题,函数也同样需要重复创建。

    寄生组合式继承

    基本思想: 在组合继承的基础上进一步优化,将Parent显示原型浅复制赋值给Child显示原型,解决组合继承创建原型多调用Parent构造函数的问题。

    function Parent(name) {
      this.name = name
      this.isRich = true
      this.banCreditCard = []
    }
    Parent.prototype.getBanCreditCard = function() {
      console.log(this.banCreditCard)
    }
    Parent.prototype.getRich = function() {
      console.log('能回去继承家产么?', this.isRich)
    }
    // 重点思想
    function inheritPrototype(child,parent) {
      let prototype = Object.create(parent.prototype)
      child.prototype = prototype
      prototype.constructor = child
    }
    inheritPrototype(Child, Parent)
    function Child(name) {
      Parent.call(this, name)
    }
    
    let child1 = new Child('瑾行')
    let child2 = new Child('七金')
    child1.banCreditCard.push('建设银行')
    child2.getBanCreditCard() // []
    child1.getRich() // 能回去继承家产么? true
    child2.getRich() // 能回去继承家产么? true
    

    寄生组合式继承是目前最完美的继承方案:只调用一次Parent的构造函数,避免在Parent.prototype上添加多余的属性和方法,原型链保持不变。可以让child1child2合理共同继承家产的同时,避免太多繁杂的事情,人生巅峰!!!

    extends

    ES6新增的extends核心思想和寄生组合继承类似。相当于寄生组合继承的语法糖。 经过babel转义如下:

    function _inherits(subClass, superClass) { 
        if (typeof superClass !== "function" && superClass !== null) { 
            throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
        } 
        // subClass.prototype = superClass.prototype
        // subClass.prototype.constructor = subClass
        subClass.prototype = Object.create(superClass && superClass.prototype, { 
            constructor: { 
                value: subClass, 
                enumerable: false, 
                writable: true, 
                configurable: true 
            } 
        });
        // subClass.__proto__ = superClass
        if (superClass) {
          Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
        }
    }
    

    起源地下载网 » 继承 | 8月更文挑战

    常见问题FAQ

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

    发表评论

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

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

    联系作者

    请选择支付方式

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