博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
class
阅读量:6226 次
发布时间:2019-06-21

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

Class

ES6当中引入了类的概念。当然类在ES6当中是基于原型的语法糖,所以,ES6中类的方法基本都可以通过原型来实现。

那么以生成一个身份证信息为例。来介绍一下ES6的类。

定义一个构造器函数 传统方式定义 function Make(name, id){ = name; = id; } Make.prototype.printName = function() { console.log(); } Make.prototype.nation = "中国"; Make.prototype.desc = "身份证生成";

ES6类的声明 class Make{ constructor(name, id) { = name; = id; } printName() { console.log(); } } Make.prototype.nation = "中国"; Make.prototype.desc = "身份证生成";

ES6当中的类像极了函数的声明。实际上

console.log(typeof Make); //function 但是实际上,class与函数声明又有本质的不同:

class 并不存在函数提升 函数可以直接调用,类声明必须使用new调用 类的继承 传统方式构造器函数继承 因为在ES6之前没有类的概念,我们更多的是使用原型继承和继承构造器函数。 在ES6之前,我们通过去集成一个构造器函数最简单的方法就是使用Parent.call(this);如下:

function Animal() { this.type = "哺乳动物" } function Dog(name) { Animal.call(this); = name; } console.log(new Dog("大黄狗")); 那么,我们的Dog构造器就继承了Animal构造器函数;Dog实例如下:

image;

ES6类的构造器函数继承 在ES6当中,继承必须使用extends关键字去继承。代码如下:

class Animal{ constructor() { this.type = "哺乳动物"; } } class Dog extends Animal{ constructor(name) { super(); = name; } } console.log(new Dog("大黄狗")); 可以看到,在ES6当中,继承一个构造器函数需要做两件事:

定义子类的时候,使用extends关键字。 在子类的构造器函数中调用super()。 这个super()实际上类似于Animal.call(this);但是又有所不同。

注意点:

super()方法必须存在且是函数调用,不然无法调用。 super()方法和call去调用有本质的不同之处。因为在类的继承当中,super()方法将会优先于Animal.call(this)执行。 原生构造器函数的继承 传统方式无法继承原生构造器函数 在ES6之前,去继承一个原生的构造器函数是做不到的。例如,我们都知道,Array是数组的构造器函数。那么,如果我们去集成这个Array的构造器函数,就可以生成一个自己的数组构造器,然后还可以添加上自己的方法。但是,这是做不到的。例如:

function MyArray() { Array.call(this,arguments); }

const myarr = new MyArray(1,2,3); MyArray.prototype = {...Array.prototype}; MyArray.constructor = MyArray; console.log(myarr);

image

结果并没有生成一个新的数组。

ES6类继承原生构造器函数 我们使用extends和super()去继承原生构造器函数,代码如下:

class MyArray extends Array{ constructor(...args) { super(...args); } }

const myarr = new MyArray(1,2,3); console.log(myarr);

image;

可以发现,我们确确实实通过了自己的构造函数生成了一个数组。那么就实现了继承原生构造器函数。我们还可以在这个子类上添加各种方法,来实现封装我们自己的数组函数。还可以调用数组上的各种快捷操作。

ES6类能继承原生构造器函数的本质原因

前面我们说过,super()方法类似于Parent.call(this);究其原因还要分析道 new 做的几件事当中去。

新生成一个对象。 将构造器函数的this指向新生成的对象。 将新生成对象通过__proto__指向构造器函数的原型。 返回新生成的对象。 在我们使用call方法去实现继承的时候,实际上,已经做到了第二件事之后。那么,在ES6之前,原生的构造器方法内部的this是不接受call方法传入的。也就是说,我们无法通过call方法去调用原生构造器上的属性和方法。导致继承失败。

在ES6的super()方法当中,super()方法将作为优先执行。那么将发生在第二件事之前。所以,相当于已经生成了一个新的数组对象,然后再将新生成对象中的this修饰为新生成的对象。那么,我就可以在这个数组对象上调用数组对象的方法了。做完这件事之后。才可以去做第二件事。这也是为什么如果没有super方法使用new会报错。因为,在没有super方法之前。第二件事也就没有办法完成,导致浏览器报错。

所以为了符合语义:

总是保证在有extends关键字的情况下使用super()方法。 super()方法写在子类构造器函数的最开头。 完成一个例子 需求:

使用类的继承,实现继承原生构造器的数组。然后通过传入电影的对象,生成数组。该实例对象具有排序方法,总是返回电影前3的电影排名。

需求代码:

const movie = new Movies({ name: "复联者联盟3", numbers: 1111 }, { name: "摔跤吧!爸爸", numbers: 998 }, { name: "捉妖记2", numbers: 1000 }, { name: "大开眼戒", numbers: 777 }, { name: "东方列车谋杀案", numbers: 2222 }); 通过传入对象,生成一个数组,该数组实现了票房数据的排序。

实现代码:

class Movies extends Array{ constructor(...movies) { super(...movies); let now = new Date(); = ${now.getMonth()+1}月${now.getDate()}日电影票房数据 }

getTop (){    return this.sort((prev, curr) => curr.numbers-prev.numbers)}getTop3 (){    let arr = this.getTop();    return arr.slice(0,3);}复制代码

}

转载于:https://juejin.im/post/5c6e9fce6fb9a049d61e2387

你可能感兴趣的文章
英特尔开源分布式深度学习平台Nauta,使用Kubernetes 和 Docker 平台运行
查看>>
【译】Apache Flink 容错机制
查看>>
Java字节码忍者禁术
查看>>
Firefox 50优化Electrolysis
查看>>
CNCF宣布Envoy项目正式毕业
查看>>
dockerfile中apt-install处理continue
查看>>
封装一个FTP工具类
查看>>
【javascript】字符串及判断方法
查看>>
link 与 controller
查看>>
实践:GNU构建系统
查看>>
扩展spring schema文件
查看>>
经典汉诺塔问题
查看>>
html5整理(一)
查看>>
spring-cloud-config的encrypt功能
查看>>
javascript引用类型之Date
查看>>
Fiddler调试(适合修复线上bug和直接调试线上问题)
查看>>
Vue+WebSocket+ES6+Canvas 制作【你画我猜】小游戏
查看>>
Java反射的封装
查看>>
精益 React 学习指南 (Lean React)- 1.1 React 介绍
查看>>
基于Flink的标准SQL操作支持
查看>>