蘑小De菇

个人技术博客

hi,我是蘑小De菇,一名前端开发者。


记录个人对技术的理解和开发过程中遇到的问题,欢迎了解更多。

理解继承

继承

继承是通过原型链实现的,实例使用原型的属性和方法属于一种继承

原型和继承的关系

  • instanceof 如果原型链出现过这个构造函数,则返回true
  • isPrototypeOf 原型方法,判断原型是否包含这个实例

继承方式

  1. 原型继承 缺点:
    1. 原型上的引用方法会在实例中共享
    2. 子构造函数的实例不能给父构造函数函数传参
    function Super() {
       this.name = '11'
       this.city =['beijing','shanghai']
     }
    
     function Son() {
       this.age='12'
     }
    
     Son.prototype = new Super()
    
     const shili = new Son()
     shili.city.push('guangzhou')
     // ahili1没法给Super传递参数
     const shili1 = new Son()
     // 下面打印是实例间共享
     console.log(shili1.city) //[ 'beijing', 'shanghai', 'guangzhou' ] 
    
  2. 盗用构造函数继承: 缺点: 盗用构造函数和构造函数模式一样,每次调用父构造函数都会创建新的属性 优点: 解决了原型继承的缺点,可以传参,实例之间引用类型不会共享

     function Super(name) {
       this.name = '11'
       this.city =['beijing',name]
     }
    
     function Son(name) {
       Super.call(this,name)
       this.age='12'
     }
    
     const shili = new Son('shanghai')
    
     shili.city.push('guangzhou')
     const shili1 = new Son('chengdu')
     console.log(shili.city) // [ 'beijing', 'shanghai', 'guangzhou' ]
     console.log(shili1.city) //[ 'beijing', 'chengdu' ]
    
  3. 组合继承 组合继承就是原型继承和盗用构造函数的组合使用 优点: 1.解决了盗用构造函数的原型函数的缺点,实例间可以共享的,放在父构造函数的原型上,需要传递参数的,放在父构造函数的函数体里 缺点: 父构造函数在子构造函数体调用一次,创建属性在子构造函数的实例上,子构造函数的原型prototype 赋值父构造函数的实例也会创建父构造函数的属性到原型上。实例上的属性会覆盖构造函数原型上的属性

    function Super(name) {
       this.name = '11'
       this.city =['beijing',name]
     }
    
     Super.prototype.sayHi= function() {
       console.log('super')
     }
    
     function Son(name) {
       Super.call(this,name)
       this.age='12'
     }
    
     Son.prototype = new Super('chengdu')
    
     console.log(Son.prototype.city) //[ 'beijing', 'chengdu' ]
    
     Son.prototype.sayHolle = function(){
       console.log('son')
     }
    
     const shili = new Son('shanghai')
    
     console.log(shili.city) //[ 'beijing', 'shanghai' ]
    
    
  4. 原型式继承 临时创建一个构造函数,把构造函数的prototype赋值,并返回这个构造函数的实例 优点: 适用于在一个对象的基础上新建另一个对象 缺点: 类似原型继承,实例共享原型上的引用类型

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

    Object.create: Object.create(原型对象,新实例初始化的一些值集合) 原型式继承在es6通过Object.create实现了,当Object.create不传第二个参数,和原型式继承一摸一样

     function object(o) {
     function F() {}
       F.prototype = o
       F.prototype.constructor = F
       return new F()
     }
    
     const shili = object({name:'11111'})
     Object.defineProperties(shili,{age:{value:'18',enumerable:true,writable:true,configurable:true}})
     // 上面的代码等价于
     Object.create({name:'11111'},{age:{value:'18',enumerable:true,writable:true,configurable:true}})
    
  5. 寄生式继承 原理是创建一个实例对象,然后强化它

    function object(o) {
     function F() {}
       F.prototype = o
       F.prototype.constructor = F
       return new F()
     }
    
     function jisheng(prop) {
       const shili = object(prop) // 不一定非要原声式继承
       shili.sayHi = ()=>{
         console.log('jishneg')
       }
    
       return shili
     }
    
     const shili = jisheng({})
    
  6. 寄生式组合继承 使用盗用构造函数创建父构造函数上的属性,父构造函数原型对象上的属性通过子构造函数原型创建 这样避免了子构造函数原型上不必要的属性创建,所以效率更高 且原型链保持不变
   function object(o) {
      function F() {}
      F.prototype = o
      F.prototype.constructor = F
      return new F()
    }

    function jsheng(superFun, sonFun) {
      const prototype = object(superFun.prototype)
      prototype.constructor = sonFun
      sonFun.prototype = prototype
    }

    function Super(name) {
      this.name = '11'
      this.city = ['beijing', name]
    }

    Super.prototype.sayHi = function() {
      console.log('super')
    }

    function Son(name) {
      Super.call(this, name)
      this.age = '12'
    }

    jsheng(Super, Son)

    const shile = new Son('shanghai')

    shile.sayHi() // super
下一篇

理解类

上一篇

理解原型