ES6躬行记(20)——类

  ES6正式将类(Class)的概念在语法层面标准化,今后不必再用构造函数模拟类的行为。而ES6引入的类本质上只是个语法糖(即代码更为简洁、语义更为清晰),其大部分功能(例如继承、封装和复用等)均可在ES5中实现,只不过现在能用更符合面向对象的语法来操作类。但诸如接口、protected修饰符等一些面向对象常用的语法,ES6没有给出相关标准。

一、创建

  在ES5时代,可以像下面这样模拟一个类,先声明一个构造函数,然后在其原型上定义共享的方法,最后与new运算符组合实例化一个类。

function People(name) {
this.name = name;
}
People.prototype.getName = function () {
return this.name;
};
var people = new People("strick");
people.getName(); //"strick"

  本节接下来的内容会与这个示例有一些关联。

1)类声明

  类的创建方式与函数类似,也有两种:类声明和类表达式。类声明必须包含名称和class关键字,下面也创建一个People类,其主体由一对花括号包裹,它的自有属性和方法都与前一个People类相同。注意,每个类有且只有一个构造函数:constructor(),如果没有显式的声明,那么会有一个空的构造函数以供调用。

class People {
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
}
var people = new People("strick");
people.getName();             //"strick"
typeof People;               //"function"
typeof People.prototype.getName;  //"function"

  在代码的最后,调用了两次typeof运算符,由于此处的People类相当于上一个示例模拟的People类,只不过写法不同,因此两次运算的计算结果都是“function”,这也从侧面再次印证ES6的类仅仅是个语法糖。

  虽然两种类非常相似,但是ES6中的类有其独有的特性,具体如下所列:

(1)类声明和即将要讲解的类表达式都不会被提升。

(2)类中的代码在执行时,会强制开启严格模式。

(3)类的所有方法都不可枚举,并且不能与new组合使用。

2)类表达式

  在类表达式中,名称是可选的,但class关键字依然是必需的。如果包含名称,那么叫做命名类表达式,反之,叫做匿名类表达式,如下所示。

var People = class {            //匿名类表达式
};
var People = class Man { //命名类表达式
};

  命名类表达式中的名称只能在类的内部访问,如果在外部贸然使用,那么就会抛出未定义的错误。下面的例子演示了名称的特点和局限。

var People = class Man {
getSelf() {
typeof Man; //"function"
Man.name; //"Man"
new Man().getAge(); //28
}
getAge() {
return 28;
}
};
var people = new People();
people.getSelf();
People.name; //"Man"
Man.name; //Man未定义的错误

  在getSelf()方法中先将typeof运算符应用于Man,然后访问Man的name属性,最后调用其实例的getAge()方法。在命名类的外部分别访问People和Man的name属性,前者能得到预期的结果,而后者却会抛出错误。

  与函数表达式类似,类表达式也能立即执行,只是要像下面这样,先在class关键字之前加new,然后在类的主体后面跟一对圆括号,里面的参数会传递给构造函数。

var people = new class {
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
}("strick");
people.getName(); //"strick"

二、成员

  类的成员既可以是普通的原型方法或自有属性,还可以是有特殊功能的构造函数、生成器、静态方法和访问器属性等,并且成员名可以是表达式。

1)自有属性

  类中的自有属性可以作为this对象的属性,并且一般都会在构造函数中执行初始化,如下所示。

class People {
constructor() {
this.name = "strick";
}
}

2)访问器属性

  在类中的访问器属性,其存取语法和ES5对象字面量中的相同,也需要get和set两个关键字,具体实现如下所示。

class People {
get prop() {
return `getter:${this.name}`;
}
set prop(value) {
this.name = value;
}
}
var people = new People();
people.prop = "strick";
console.log(people.prop); //"getter:strick"

  访问器属性还有一个便捷的地方,就是它和原型方法一样,也能被子类继承。

3)计算成员名

  类中的成员名既可以是标识符,也可以是要计算的表达式(如下代码所示),其声明语法和ES5对象字面量中的相同,也需要用一对方括号包裹。

var method = "getAge";
class People {
["get" + "Name"]() {
return "strick";
}
[method]() {
return 28;
}
}
var people = new People();
people.getName();   //"strick"
people.getAge(); //28

4)生成器

  只要在某个方法之前加上星号(*),那么这个方法就能变为生成器,注意观察下面代码中的getName()方法。关于生成器的具体用法可以参考第19篇

class People {
*getName() {
yield "strick";
}
}
var people = new People(),
iterator = people.getName();
iterator.next(); //{value: "strick", done: false}

  如果方法的名称是内置符号Symbol.iterator并且是一个生成器方法,那么就成功的为类创建了一个默认的迭代器,这也意味着类的实例能被for-of循环,具体实现可参考下面的代码。

class People {
*[Symbol.iterator]() {
for (const item of [1, 2]) {
yield item;
}
}
}
var people = new People();
/********************
1
2
********************/
for(var value of people) {
console.log(value);
}

5)静态方法

  ES6新增了static关键字,可把类中的方法(除了构造函数)定义成静态的。要调用静态方法只能通过类本身,而不是实例化的类,如下代码所示。除了方法之外,static关键字还适用于访问器属性。

class People {
static getName() {
return "strick";
}
}
People.getName(); //"strick"

  虽然ES6明确提出了静态方法,但是没有将静态属性一并标准化。如果要使用静态属性,可以像下面这样用变通的方式定义。

People.age = 28;

ES6-类(Class)的更多相关文章

  1. React与ES6(三)ES6类和方法绑定

    React与ES6系列: React与ES6(一)开篇介绍 React和ES6(二)ES6的类和ES7的property initializer React与ES6(三)ES6类和方法绑定 React ...

  2. 封装的通过微信JS-SDK实现自定义分享到朋友圈或者朋友的ES6类!

    引言: 我们经常在做微信H5的过程中需要自定义分享网页,这个如何实现呢?请看如下的封装的ES6类及使用说明! /** * @jssdk js对象,包括appId,timestamp,nonceStr, ...

  3. ES6 类

    ES6之前没有类的概念,一般采用以下方式来模仿类 基本的类声明语法 私有属性是实例中的属性,不会出现在原型上,且只能在类的构造函数中创建所有私有属性 PersonClass声明实际上创建了一个具有构造 ...

  4. ES6 类(Class)基本用法和静态属性+方法详解

    原文地址:http://blog.csdn.net/pcaxb/article/details/53759637 ES6 类(Class)基本用法和静态属性+方法详解 JavaScript语言的传统方 ...

  5. Es6 类的关键 super、static、constructor、new.target

    ES6引入了Class(类)这个概念,作为对象的模板,通过class关键字,可以定义类.基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对 ...

  6. Es6 类class的关键 super、static、constructor、new.target

    ES6引入了Class(类)这个概念,作为对象的模板,通过class关键字,可以定义类.基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对 ...

  7. es5继承和es6类和继承

    es6新增关键字class,代表类,其实相当于代替了es5的构造函数 通过构造函数可以创建一个对象实例,那么通过class也可以创建一个对象实列 /* es5 创建一个person 构造函数 */ f ...

  8. ES6类的继承

    ES6 引入了关键字class来定义一个类,constructor是构造方法,this代表实例对象. constructor相当于python的init 而this 则相当于self 类之间通过ext ...

  9. ES6类与模块

    class Animal { // 构造方法,实例化的时候会被调用,如果不指定,那么会有一个不带参数的默认构造函数 constructor(name, color) { this.name = nam ...

  10. ES6(类)

    类的概念 1.基本定义 2.继承 继承如何传递参数?(super) 定义自己属性的时候调用 this 一定要在 super 之后(在继承关系中,子类的构造函数如果用 super 传递参数的过程中,su ...

随机推荐

  1. GO 文件读取常用的方法

    方式1: 一行一行的方式读取 其中常用的方法就有:ReadString,ReadLine,ReadBytes ReadLine 返回单个行,不包括行尾字节,就是说,返回的内容不包括\n或者\r\n,返 ...

  2. Python爬虫:BeautifulSoup用法总结

    原文 BeautifulSoup是一个解析HTML或XML文件的第三方库.HTML或XML文件可以用DOM模型解释.一般包含三种节点: 元素节点 - 通常指HTML 或 XML的标签 文本节点 - 标 ...

  3. redis登录及设置密码

    redis服务开启 : ./redis-server /opt/redisConf/redis.conf 1,查询默认密码 127.0.0.1:6379> config get requirep ...

  4. MongoDB 分片管理(二)查看网络连接

    1.1 查看连接统计 connPoolStats,查看mongos与mongod之间的连接信息,并可得知服务器 上打开的所有连接 1.2 限制连接数量

  5. Elasticsearch 索引文档的增删改查

    利用Elasticsearch-head可以在界面上(http://127.0.0.1:9100/)对索引进行增删改查 1.RESTful接口使用方法 为了方便直观我们使用Head插件提供的接口进行演 ...

  6. 二分算法题目训练(一)——Shell Pyramid详解

    HDU2446——Shell Pyramid 详解 Shell Pyramid 题目描述(Google 翻译的) 在17世纪,由于雷鸣般的喧嚣,浓烟和炽热的火焰,海上的战斗与现代战争一样.但那时,大炮 ...

  7. python踩坑记录篇,持续更新

    问题1:python语法错误 错误日志如下: print(a[2])    ^IndentationError: unexpected indent [解决方案]:缩进代码错误导致,将print的缩进 ...

  8. 卸载ros

    #卸载 ros sudo apt-get autoremove ros-*

  9. linux 编写定时任务,查询服务是否挂掉

    shell 脚本 #!/bin/bash a=`netstat -unltp|grep fdfs|wc -l` echo "$a" if [ "$a" -ne ...

  10. dp之斜率优化

    前几天想练练思维,所以从cf上随便找了一道dp题,看完题意后第一感觉很简单,就是简单的区间dp题,但是看到数据范围的我顿时就懵了,(1≤n≤105) emmmmmmmm,按照普通的思路肯定会超时的.. ...