• ES5与ES6中的继承


    ES5继承
    在ES5中没有类的概念,所以一般都是基于原型链继承,具体的继承方法有以下几种:

    父类:
    function Father (name) {
      this.name = name || 'sam'
      this.sleep = function () { // 实例方法
        return this.name + '正在睡觉'
      }
    }
    Father.prototype.eat = funciton () { // 原型方法
      return this.name + '正在吃饭'
    }

    一,原型链继承
    核心:将父类的实例作为子类的原型

    子类:
    function Son () { 
      this.age = 12
    }
    Son.prototype = new Father()
    Son.prototype.name = 'Sam'
    var son = new Son()
    document.write(son.age)
    document.write(son.name) // Sam
    document.write(son.sleep()) // Sam正在睡觉
    document.write(son.eat()) // Sam正在吃饭

    优点:

    (1)非常纯粹的继承关系,实例是子类的实例,也是父类的实例
    (2)父类新增的属性和方法,子类都能访问到
    (3)简单,易于实现
    缺点:

    (1)无法实现多继承
    (2)来自原型对象的引用属性是所有子类实例共享的
    (3)创建子类实例时,无法向父类的构造函数传递参数

    二,构造继承
    核心:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类

    子类:
    function Son (age) {
      Father.call(this) //实现了继承 
      this.age = age
    }
    var son = new Son()
    console.log(son.name) // 返回sam
    console.log(son.sleep()) // 返回sam正在睡觉
    console.log(son.eat()) // 报错Uncaught TypeError

    优点:
    (1)子类创建时,可以通过call或者apply向父类传递参数
    (2)可以实现多继承(call多个父类对象)
    缺点:
    (1)实例并不是父类的实例,只是子类的实例
    (2)只能继承父类的实例属性和方法,不能继承原型属性和方法
    (3)无法实现函数复用,每个子类都有父类实例函数的副本,影响性能
    三,实例继承
    核心:为父类实例添加新特性,作为子类实例返回

    子类:
    function Son (name) {
    var instance = new Father() instance.name = name || 'Tom' return instance } var son = new Son() console.log(son.name) console.log(son.sleep()) console.log(son.eat())

    缺点:
    (1)实例是父类的实例,不是子类的实例
    (2)不支持多继承
    四,组合继承
    核心:通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用

    子类:
    function Son (age) {
      Father.call(this,'sam')
      this.age = age
    }
    Son.prototype = new Father()
    var son = new Son()
    console.log(son.name)
    console.log(son.eat())
    console.log(son.sleep())

    优点:
    (1)可以继承实例属性和方法,还可以继承原型属性和方法
    (2)既是子类的实例,也是父类的实例
    (3)不存在引用属性共享问题
    (4)可传参
    (5)函数可复用
    缺点:调用了两次父类构造函数,生成了两份实例
    ES6继承
    ES6里面引入了类class的概念,class可以通过extends关键字实现继承,这比ES5通过修改原型链实现继承,要清晰和方便很多
    父类(关于ES6中通过class定义一个实例对象的方法这里略过)

    class Father {
      constructor (name) {
        this.name =name
      }
      eat () {
        return this.name + '正在吃饭'
      }
      sleep () {
        return this.name + '正在睡觉'
      }
    } 
    子类
    class Son extends Father {
    }
    class Son extends Father {
      constructor () {
        super()
      }
    }

    以上两种写法是相等的。如果子类中没有定义constructor,这个方法会被默认添加,不管有没有显示定义,任何一个子类都有constructor方法。

    子类
    class Son extends Father {
      constructor (color) {
        this.color = color
      }
    }
    var son = new Son();
    console.log(son.color) // 报错

    在子类的构造函数中,如果用了constructor方法,则必须调用super方法。只有调用super之后,才可以使用this关键字,否则会报错。这是因为子类实例的构建,是基于对父类实例的加工,只有super方法才能返回父类实例

    class Son extends Father {
      constructor (name,age) {
        super (name)
        this.age = age
      }
      play () {
        return super.eat()+ '正在玩耍' 
      }
    }
    var son = new Son('sam')
    console.log(son.play())
  • 相关阅读:
    Flink sql 之 AsyncIO与LookupJoin的几个疑问 (源码分析)
    Flink sql 之 微批处理与MiniBatchIntervalInferRule (源码分析)
    Go学习例子(六)
    Go学习例子(五)
    Go学习例子(二)
    Go学习例子(四)
    Go学习例子(一)
    Go学习例子(三)
    cookie,session傻傻分不清楚?
    Linux服务器查看日志
  • 原文地址:https://www.cnblogs.com/cn-andy/p/8590218.html
Copyright © 2020-2023  润新知