一个小小的总结,主要关注以下三个问题: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. java 枚举类(简单使用)

    直接上代码 用法一(常量): package com.ou.test; import com.sun.corba.se.impl.util.SUNVMCID; public class Enum { ...

  2. 查看hive的信息

    一.Hive下查看数据表信息的方法方法1:查看表的字段信息desc table_name; 方法2:查看表的字段信息及元数据存储路径desc extended table_name; 方法3:查看表的 ...

  3. AJAX增删查

    数据库 CREATE DATABASE crmweb; CREATE TABLE `customerstatus` ( `id` bigint(20) NOT NULL AUTO_INCREMENT ...

  4. sln、db、opendb、vcxproj、filters、user文件跟踪说明

    工程文件控制 vs工程中,往往包含:.sln ..db  ..opendb 文件 sln文件 为工程属性文件,是我们必须添加到版本控制中的, db文件,是项目编译时生成的数据库文件,非常的大,占用空间 ...

  5. 《剑指offer》算法题第十二天

    今天是<剑指offer>算法题系列的最后一天了,但是这个系列并没有包括书上的所有题目,因为正如第一天所说,这些代码是在牛客网上写并且测试的,但是牛客网上并没有涵盖书上所有的题目. 今日题目 ...

  6. 推荐系统系列(四):PNN理论与实践

    背景 上一篇文章介绍了FNN [2],在FM的基础上引入了DNN对特征进行高阶组合提高模型表现.但FNN并不是完美的,针对FNN的缺点上交与UCL于2016年联合提出一种新的改进模型PNN(Produ ...

  7. [CSP-S模拟测试]:A(数学)

    题目传送门(内部题44) 输入格式 一行四个整数,分别表示$S,T,a,b$. 输出格式 输出最小步数,数据保证有解. 样例 样例输入: 10 28 4 2 样例输出: 数据范围与提示 样例解释: 先 ...

  8. flask中models设计

    1. 自关联 class Comment(db.Model): __tablename__ = 'albumy_comment' id = db.Column(db.Integer, primary_ ...

  9. linux中~和/,$和#的区别

    /是目录层的分隔.表示符.只有一个/表明是root,/etc/表明是根目录下面的etc目录(当然目录最后不需要/,但有/直接表明他是目录,没有末尾的/,那么/etc需要检测一下确定是目录还是文件,虽然 ...

  10. ANTLR4将JSON翻译成XML

    实现功能:构建一个JSON到XML的翻译器. antlr4文件: grammar JSON; json : object | array ; object : '{' pair (',' pair)* ...