博客
关于我
ES6之class的继承
阅读量:519 次
发布时间:2019-03-07

本文共 3982 字,大约阅读时间需要 13 分钟。

class语法为我们提供了构造函数的语法糖,响应的,也给我们提供了ES5通过原型链实现继承提供了extends关键字实现继承。继承这个概念对面后台应该也是非常常见。

通过extends继承,语法:

class User{}

class Son extends User{}

继承之后Son可以使用User类的所有属性和方法:

class User{    constructor(a){        this.a = a;        this.b = 10;    }    eat(){        console.log('user eat');    }}class Son extends User{    constructor(b, c){      super(b);      this.c = c;    }    sum(){        console.log(this.a, this.b, this.c);    }}var son = new Son(1, 2);son.eat();//user eatson.sum();//1 10 2

子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用super方法,子类就得不到this对象。

如果子类没有定义constructor方法,这个方法会被默认添加,需要注意的地方是,在子类的构造函数中,只有调用super之后,才可以使用this关键字,否则会报错。这是因为子类实例的构建,基于父类实例,只有super方法才能调用父类实例。静态方法也会继承。

通过Object.getPrototypeOf获取父类:

class User{}class Son extends User{}console.log(Object.getPrototypeOf(Son));//class User{}

Super关键字有两个用法,一个是函数,一个是对象。当做函数的时候只能在子类的构造函数中使用,子类必须调用,也就是constructor里面,其他地方会报错:

class User{}class Son extends User{    eat(){        super();    }}//Uncaught SyntaxError: 'super' keyword unexpected here

作为对象的时候,普通方法super指向父类的原型对象,在静态方法中指向父类;

class User{  constructor(){      this.a = 1;      this.b = 1;  }  eat(){      console.log(this.b);//10      return 2  }}class Son extends User{   constructor(){       super();       this.b = 10;       this.c = 20;       console.log(super.c);//undefined       console.log(this.c);//20   }   talk(){       console.log(super.a);//undefined       console.log(super.eat());//2   }}var son = new Son();son.talk();

普通方法中,super指向父类原型对象(constructor里面是实例的属性),所以调用eat方法可以,a就获取不到。如果属性定义在父类的原型对象上,可以获取。子类调用super的时候,this指向当前子类的实例。对super赋值相当于为this赋值。

静态方法中,super指向父类,也就是User类:

class User{    constructor(){        this.a = 10;    }    static eat(val) {        console.log('static', val);    }    eat(val) {        console.log('instance', val);    }    static talk(){        console.log(this.a);    }}class Son extends User{    constructor(){        super();        this.a = 20;    }    static eat(val) {        super.eat(val);    }    eat(val) {        super.eat(val);    }    static talk(){        super.talk();    }}Son.a = 30;Son.talk();//30Son.eat(1); // static 1var son = new Son();son.eat(2); // instance 2

子类Static eat方法super指向父类,所以调用父类static eat方法,子类普通方法eat指向父类原型对象,所以调用父类普通方法eat。子类静态方法super内部this指向当前子类,而不是实例或者原型对象,所以子类Son调用talk方法,输出的是30。

使用super必须指定是函数还是对象,否则报错。

类也是有prototype和__proto__属性的,相应的构成原型链:

子类的__proto__属性是构造函数的继承,指向父类

子类的prototype属性的__proto__属性,表示方法的继承,指向父类的prototype。

class User{}class Son extends User{}console.log(Son.__proto__ === User); // trueconsole.log(Son.prototype.__proto__ === User.prototype); // true

因为类的继承是通过setPrototypeOf。

子类实例的__proto__属性的__proto__属性,指向父类实例的__proto__属性。也就是说,子类的原型的原型,是父类的原型:

class User{}class Son extends User{}console.log(Son.__proto__ === User.__proto__); // falseconsole.log(Son.__proto__.__proto__ === User.__proto__); // true

原生的构造函数Boolean()、Number()、String()、Array()、Date()、Function()、RegExp()、Error()、Object()在ES5之前是无法继承的,ES6可以自定义原生数据结构:

class MyArray extends Array {    constructor(...args) {        super(...args);    }}var arr = new MyArray();

Misin模式就是把多个对象合成一个新的对象,新对象有各个组成的接口:

var a = {}var b = {}var c = {...a, ...b}

阮大神提供了class的Mixin:

function mix(...mixins) {    class Mix {        constructor() {            for (let mixin of mixins) {                copyProperties(this, new mixin()); // 拷贝实例属性            }        }    }    for (let mixin of mixins) {        copyProperties(Mix, mixin); // 拷贝静态属性        copyProperties(Mix.prototype, mixin.prototype); // 拷贝原型属性    }    return Mix;}function copyProperties(target, source) {    for (let key of Reflect.ownKeys(source)) {        if ( key !== 'constructor'            && key !== 'prototype'            && key !== 'name'        ) {            let desc = Object.getOwnPropertyDescriptor(source, key);            Object.defineProperty(target, key, desc);        }    }}

使用:

class DistributedEdit extends mix(Loggable, Serializable) {// ...}

建议可以使用了看看打印的数据。

转载地址:http://jennz.baihongyu.com/

你可能感兴趣的文章
nifi使用过程-常见问题-以及入门总结---大数据之Nifi工作笔记0012
查看>>
NIFI分页获取Mysql数据_导入到Hbase中_并可通过phoenix客户端查询_含金量很高的一篇_搞了好久_实际操作05---大数据之Nifi工作笔记0045
查看>>
NIFI分页获取Postgresql数据到Hbase中_实际操作---大数据之Nifi工作笔记0049
查看>>
NIFI同步MySql数据_到SqlServer_错误_驱动程序无法通过使用安全套接字层(SSL)加密与SQL Server_Navicat连接SqlServer---大数据之Nifi工作笔记0047
查看>>
Nifi同步过程中报错create_time字段找不到_实际目标表和源表中没有这个字段---大数据之Nifi工作笔记0066
查看>>
NIFI大数据进阶_FlowFile拓扑_对FlowFile内容和属性的修改删除添加_介绍和描述_以及实际操作---大数据之Nifi工作笔记0023
查看>>
NIFI大数据进阶_FlowFile生成器_GenerateFlowFile处理器_ReplaceText处理器_处理器介绍_处理过程说明---大数据之Nifi工作笔记0019
查看>>
NIFI大数据进阶_Json内容转换为Hive支持的文本格式_操作方法说明_01_EvaluteJsonPath处理器---大数据之Nifi工作笔记0031
查看>>
NIFI大数据进阶_Kafka使用相关说明_实际操作Kafka消费者处理器_来消费kafka数据---大数据之Nifi工作笔记0037
查看>>
NIFI大数据进阶_Kafka使用相关说明_实际操作Kafka生产者---大数据之Nifi工作笔记0036
查看>>
NIFI大数据进阶_NIFI的模板和组的使用-介绍和实际操作_创建组_嵌套组_模板创建下载_导入---大数据之Nifi工作笔记0022
查看>>
NIFI大数据进阶_NIFI监控功能实际操作_Summary查看系统和处理器运行情况_viewDataProvenance查看_---大数据之Nifi工作笔记0026
查看>>
NIFI大数据进阶_NIFI监控的强大功能介绍_处理器面板_进程组面板_summary监控_data_provenance事件源---大数据之Nifi工作笔记0025
查看>>
NIFI大数据进阶_NIFI集群知识点_认识NIFI集群以及集群的组成部分---大数据之Nifi工作笔记0014
查看>>
NIFI大数据进阶_NIFI集群知识点_集群的断开_重连_退役_卸载_总结---大数据之Nifi工作笔记0018
查看>>
NIFI大数据进阶_内嵌ZK模式集群1_搭建过程说明---大数据之Nifi工作笔记0015
查看>>
NIFI大数据进阶_外部ZK模式集群1_实际操作搭建NIFI外部ZK模式集群---大数据之Nifi工作笔记0017
查看>>
NIFI大数据进阶_实时同步MySql的数据到Hive中去_可增量同步_实时监控MySql数据库变化_操作方法说明_01---大数据之Nifi工作笔记0033
查看>>
NIFI大数据进阶_离线同步MySql数据到HDFS_01_实际操作---大数据之Nifi工作笔记0029
查看>>
NIFI大数据进阶_离线同步MySql数据到HDFS_02_实际操作_splitjson处理器_puthdfs处理器_querydatabasetable处理器---大数据之Nifi工作笔记0030
查看>>