一个小小的总结,主要关注以下三个问题:ES5的继承方式,ES5的继承与ES6的继承的区别,ES6的super的几种使用方式以及其中this的指向。

From http://supermaryy.com

一、ES5的继承

JS实现继承的几种方式

MDN | Object.create | 用 Object.create 实现类式继承

继承可以分为对象实例的继承,类的继承

二、ES6的继承

Class B extends A { } 中的A可以是个class,还可以是个有prototype属性的函数

三、ES5继承与ES6继承的区别

  1. this的区别

    ES5 的继承,实质是先创造子类的实例对象 this ,然后再将父类的方法添加到 this 上面(Parent.apply(this) )。ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到 this 上面(所以必须先调用 super 方法),然后再用子类的构造函数修改 this 。

  2. 原型链ES6有两条

    class A { }
    class B extends A { } B.__proto__ === A // true
    B.prototype.__proto__ === A.prototype // true

    这样的结果是因为,类的继承是按照下面的模式实现的。

    class A { }
    class B { }
    // B 的实例继承 A 的实例
    Object.setPrototypeOf(B.prototype, A.prototype);
    // B 继承 A 的静态属性
    Object.setPrototypeOf(B, A);
    const b = new B(); //setPrototypeOf的内部实现
    Object.setPrototypeOf = function (obj, proto) {
    obj.__proto__ = proto;
    return obj;
    }
    //但是setPrototypeOf会有性能问题,通常推荐使用Object.create
  3. ES6可以继承原生构造函数,而ES5不能

    1. 原生构造函数有:Boolean()、Number()、String()、Array()、Date()、Function()、RegExp()、Error()、Object()
    2. 原因:

      • ES5 是先新建子类的实例对象 this ,再将父类的属性添加到子类上,由于父类的内部属性无法获取,导致无法继承原生的构造函数。

      • ES6 允许继承原生构造函数定义子类,因为 ES6 是先新建父类的实例对象 this ,然后再用子类的构造函数修饰 this ,使得父类的所有行为都可以继承。

    3. 继承 Object 的子类,有一个 行为差异 。

      class NewObj extends Object{
      constructor(){
      super(...arguments);
      }
      }
      var o = new NewObj({attr: true});
      o.attr === true // false

      上面代码中, NewObj 继承了 Object ,但是无法通过 super 方法向父类 Object 传参。这是因为 ES6 改变了 Object 构造函数的行为,一旦发现 Object 方法不是通过 new Object() 这种形式调用,ES6 规定 Object 构造函数会忽略参数。

四、ES6的super及其this

  1. 作为函数:在子类构造函数中调用 super() ,super相当于父类constructor

  2. 作为对象:

    • 在子类 构造函数或普通函数 中使用 super.methodA() ,super相当于父类原型

      此时methodA中的this指向子类实例

    • 在子类 静态方法 中使用 super.methodB() ,super指向父类而非原型,此时的methodB指的是父类的静态方法methodB

      此时methodB中的this指向子类,所以只能通过this访问到子类的静态方法和属性

  3. 在子类中使用super 给属性赋值 super.father_prop = 1 ,相当于子类的this this.father_prop=1

    class A {
    constructor() {
    this.x = 1;
    }
    } class B extends A {
    constructor() {
    super();
    this.x = 2;
    super.x = 3;
    console.log(super.x); // undefined
    console.log(this.x); // 3
    }
    change(){
    super.x = 4
    console.log(super.x); //undefined
    console.log(this.x); // 4
    }
    }
    let b = new B();
    b.change()
  4. 使用 super 的时候,必须显式指定是作为函数、还是作为对象使用,否则会报错。

    class A {}
    
    class B extends A {
    constructor() {
    super();
    console.log(super); // 报错
    }
    }

继承以及Super的更多相关文章

  1. 继承 派生 super()经典类 新式类

    '''1什么是继承? 继承一种新建类的方式,在python中支持一个儿子继承多个爹 新建的类称为子类的或者派生类 父类有可以称为基类或者超类 子类会‘遗传’父类的属性 2 为什么要用继承 减少代码冗余 ...

  2. [python] 在 python2和3中关于类继承的 super方法简要说明

    下面举一个例子,同样的代码使用 python2 和 python3 写的,大家注意两段程序中红色加粗的部分: python2的类继承使用super方法: #-*- coding:utf-8 -*- ' ...

  3. python's twenty day for me 继承 和 super()方法

    super(): 在单继承中就是单纯的寻找父类. 在多继承中就是根据子节点所在图 的mro顺序,找寻下一个类. 遇到多继承和super(): 对象.方法 1,找到这个对象对应的类. 2,将这个类的所有 ...

  4. 继承、super、this、抽象类

    继承.super.this.抽象类 继承.super.this.抽象类 继承.super.this.抽象类 继承.super.this.抽象类 继承.super.this.抽象类

  5. 关于Python中的类普通继承与super函数继承

    关于Python中的类普通继承与super函数继承 1.super只能用于新式类 2.多重继承super可以保公共父类仅被执行一次 一.首先看下普通继承的写法 二.再看看super继承的写法 参考链接 ...

  6. Python大神必须掌握的技能:多继承、super和MRO算法

    本文主要以Python3.x为例讲解Python多继承.super以及MRO算法. 1. Python中的继承 任何面向对象编程语言都会支持继承,Python也不例外.但Python语言却是少数几个支 ...

  7. python语言中多继承中super调用所有父类的方法以及要用到的MRO顺序

    在python多继承中,利用super().父类方法,可以调用所有父类,从而在重写的状态下,再次对所有父类的调用! 例: print("******多继承使用super().__init__ ...

  8. 01 语言基础+高级:1-4 接口与多态_day09【继承、super、this、抽象类】

    day09[继承.super.this.抽象类] 三大特性——继承方法重写super关键字this关键字抽象类 教学目标能够解释类名作为参数和返回值类型能够写出类的继承格式能够说出继承的特点能够说出子 ...

  9. 为了讲明白继承和super、this关键字,群主发了20块钱群红包

    摘要:以群主发红包为例,带你深入了解继承和super.this关键字. 本文分享自华为云社区<群主发红包带你深入了解继承和super.this关键字>,作者:共饮一杯无 . 需求 群主发随 ...

  10. es6 Class的继承extends & super

    Class之间可以通过extends关键字,实现继承. 子类会继承父类的属性和方法. class Point { constructor(x, y) { this.x = x; this.y = y; ...

随机推荐

  1. axios 请求多个接口

    axios.all([ axios.get('https://api.github.com/xxx/1'), axios.get('https://api.github.com/xxx/2') ]) ...

  2. context:component-scan 注解的扫描

    <context:component-scan base-package="com.matt.cloud"/> bean-context中 spring.handler ...

  3. Hadoop-No.1之数据存储选型

    文件格式 Hadoop支持多种面向数据存储的文件格式,包括纯文本和Hadoop特有的格式,如SequenceFile.还有一些更加复杂但功能更加丰富的格式可供选择,如Avro与Parquet.不同的格 ...

  4. 04 vue-cli 脚手架、webpack-simple模板项目生成、组件使用

    alice https://www.cnblogs.com/alice-bj/p/9317504.html https://www.cnblogs.com/alice-bj/p/9318069.htm ...

  5. Linux 常用命令备忘

    安装wget 方便联网下载:  centos : sudo yum -y install wget 安装vim   :  yum -y install vim* set nu              ...

  6. IE8下,去除iframe的边框

    iframe边框通过css设定在FF下正常在ie下却还存在边框,设置frameborder="0"和border="0"可以去掉讨厌的iframe边框 < ...

  7. 字符单链表识别数字,字母,其它字符,并分为三个循环链表的算法c++实现

    已知一个单链表中的数据元素含有三类字符(即字母字符,数字字符和其它字符),试编写算法,构造三个循环链表,使每个循环链表中只含有同一类的字符,且利用原表中的结点空间作为这三个表的结点空间. 实现源代码: ...

  8. HZOJ 20190727 T2 单(树上dp+乱搞?+乱推式子?+dfs?)

    考试T2,考试时想到了40pts解法,即对于求b数组,随便瞎搞一下就oxxk,求a的话,很明显的高斯消元,但考试时不会打+没开double挂成10pts(我真sb),感觉考试策略还是不够成熟,而且感觉 ...

  9. 【CUDA 基础】3.6 动态并行

    title: [CUDA 基础]3.6 动态并行 categories: - CUDA - Freshman tags: - 动态并行 - 嵌套执行 - 隐式同步 toc: true date: 20 ...

  10. vue添加外部js

    1.新建节点 const s = document.createElement("script"); 2.设置节点属性 s.type = "text/javascript ...