zoukankan      html  css  js  c++  java
  • JS中继承的几种实现方式

    继承的核心就是将父类的原型(prototype)赋值给子类,同时将构造函数(constructor)指回子类,既保证了不会有多余的父类属性,又保证子类能找到自身的构造函数。

    1.原型链的继承

     1 function Father(){
     2   this.firstName = 'wang',
     3   this.action = function(){
     4     console.info('super')
     5   }
     6 }
     7 Father.prototype.sayHi = function(){
     8   console.info('hi')
     9 }
    10 // 子类的原型指向父类的原型
    11 Son.prototype = Father.prototype
    12 Son.prototype.constructor = Son // 需要手动将constructor指回来,不然构造函数指向父类
    13 // 子类只能继承父类原型上的属性和方法,不能继承父类本身的属性
    14 let s = new Son()
    15 s.sayHi() // hi
    16 console.info(s.firstName) //获取不到父类自身的属性,undefined
    17 console.info(s.action) //获取不到父类自身的属性,undefined
    弊端:需要手动改回constructor,不能继承父类自身属性
     
    基于原型的继承还有一种实现:
     1 function Father(){
     2   this.data = [1]
     3   this.firstName = 'wang',
     4   this.action = function(){
     5     console.info('super')
     6   }
     7 }
     8 Father.prototype.sayHi = function(){
     9   console.info('hi')
    10 }
    11 function SonOther(){
    12 }
    13 SonOther.prototype = new Father()
    14 SonOther.prototype.constructor = SonOther
    15 let so1 = new SonOther()
    16 let so2 = new SonOther()
    17 // 能继承父类自身的属性
    18 console.info(so1.firstName) // wang
    19 so2.sayHi()  // hi
    20 // 但是数据是共享的
    21 so1.data.push(2)
    22 console.info(so2.data) // [1, 2] 
    弊端:需要手动改回constructor,子类对象属性共享

    2.借助构造函数继承

    1 function Son(){
    2   Father.call(this) // Father.apply(this)
    3 }
    4  
    5 let s = new Son()
    6 let s2 = new Son()
    7 console.info(s.data.push(2))
    8 console.info(s.data, s2.data) // [ 1, 2 ] [ 1 ] 不会共享数据
    9 console.info(s.sayHi) // 不能继承父类原型中的方法 
    弊端:只能继承父类自身的属性

    3.组合式继承   构造函数+原型链

    1 function Son(){
    2   Father.call(this) // Father.apply(this)
    3 }
    4  
    5 Son.prototype = new Father() 
    优点:能继承父类自身及原型链上的方法
    弊端:调用了两次父类的构造函数,造成内存浪费

    4.寄生式继承

    通过一个函数在内部给对象添加属性和方法
     1 let father = {
     2   name: 'f',
     3   age: 30
     4 }
     5  
     6 function createObj(original){
     7   let obj = Object.create(original)
     8   obj.sayHi = function(){
     9     console.info('hi')
    10   }
    11   return obj
    12 }
    13  
    14 let s = createObj(father)
    15 console.info(s.name)
    16 s.sayHi()
    17  
    弊端:子类对象共享属性

    5.寄生组合继承

     1 function inheritPrototype(subType, superType){
     2   let prototype = Object.create(subType.prototype)
     3   subType.prototype = prototype
     4   subType.prototype.constructor = subType
     5 }
     6  
     7 function Son(){
     8   Father.call(this)
     9 }
    10 inheritPrototype(Son, Father)
    11  
    12 let son = new Son()
    13 console.info(son)

    6.类的继承

    要点:使用extends指明父类,构造函数中写super
     1 class Parent {
     2   constructor(){
     3     this.name = 'f'
     4   }
     5   sayHi(){
     6     console.info('hi')
     7   }
     8 }
     9  
    10 class Child extends Parent {
    11   constructor(value){
    12     super(value)
    13     this.val = value
    14   }
    15 }
    16  
    17 let child = new Child('899.5')
    18 console.info(child.name, child.val) // f 899.5
    19 child.sayHi() // hi
  • 相关阅读:
    html学习之——标签语义化
    前端学习之---性能优化
    git学习之---如何把一个写好的项目传到GitHub上
    css学习体会之——块级元素,行内元素长宽设置
    部署ingress-nginx
    K8S
    ELK-Trie树
    ELK 日常问题处理
    GFS 日常操作
    MegaCli修复RAID5
  • 原文地址:https://www.cnblogs.com/jyughynj/p/13445773.html
Copyright © 2011-2022 走看看