JS - ES2015/ES6新特性详解4(类、模块、Promises、模板字符串)
相关文章系列:
JS - ES2015/ES6新特性详解1(let、const、For..of循环、迭代器、生成器)
JS - ES2015/ES6新特性详解2(Set, WeakSet, Map, WeakMap、箭头函数)
JS - ES2015/ES6新特性详解3(默认参数、不定参数、扩展运算符、解构)
[当前文章] JS - ES2015/ES6新特性详解4(类、模块、Promises、模板字符串)
JS - ES2015/ES6新特性详解5(代理、反射、Symbols、Unicode编码)
JS - ES2015/ES6新特性详解6(二进制和八进制、尾调用、其他新增的API)
JS - ES2015/ES6新特性详解1(let、const、For..of循环、迭代器、生成器)
JS - ES2015/ES6新特性详解2(Set, WeakSet, Map, WeakMap、箭头函数)
JS - ES2015/ES6新特性详解3(默认参数、不定参数、扩展运算符、解构)
[当前文章] JS - ES2015/ES6新特性详解4(类、模块、Promises、模板字符串)
JS - ES2015/ES6新特性详解5(代理、反射、Symbols、Unicode编码)
JS - ES2015/ES6新特性详解6(二进制和八进制、尾调用、其他新增的API)
十、类(class, extends, super)
在 ES5 中,我们进行面向对象编程时使用构造函数来创建对象。而在 ES6 中,使用 Class 语法糖可以很方便地实现类及其相关继承代码。
- 下面代码首先用 class 定义了一个“类”,可以看到里面有一个 constructor 方法,这就是构造方法,而 this 关键字则代表实例对象。简单地说,constructor 内定义的方法和属性是实例对象自己的,而 constructor 外定义的方法和属性则是所有实例对象可以共享的。
- Class 之间可以通过 extends 关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便地多。下面定义了一个 Cat 类,该类通过 extends 关键字,继承了 Animal 类的所有属性和方法。
- super 关键字,它指代父类的实例(即父类的 this 对象)。子类必须在 constructor 方法中调用 super 方法,否则新建实例时会报错。这是因为子类没有自己的 this 对象,而是继承父类的 this 对象,然后对其进行加工。如果不调用 super 方法,子类就得不到 this 对象。
- ES6 的继承机制,实质是先创造父类的实例对象 this(所以必须先调用 super 方法),然后再用子类的构造函数修改 this。
//父类 class Animal { constructor(){ this.type = 'animal' } says(say){ console.log(this.type + ' says ' + say) } } //子类 class Cat extends Animal { constructor(){ super() this.type = 'cat' } } //创建父类对象并调用 let animal = new Animal() animal.says('hello') //animal says hello //创建子类对象并调用 let cat = new Cat() cat.says('hello') //cat says hello

十一、可以继承内置函数(原生类)
在 ES2015 中,我们可以创建内建对象,如 Array,Date 以及 DOMElement 的子类。
// 创建Array的子类 class CustomArray extends Array { } var a = new CustomArray(); a[0] = 2 console.log(a[0])

十二、模块(Modules)
过去我们实现 module 功能,得利用第三方提供的一些方案,主要有:CommonJS、AMD、CMD。而 ES6 有了自己的 module 功能,它实现非常简单,可以成为服务器和浏览器通用的模块解决方案。
- 一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。
- export 命令用于规定模块的对外接口。
- import 命令用于输入其他模块提供的功能。
- ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。
使用样例1:使用export命令规定对外接口
(1)下面我们在 Node.js 中创建一个模块,文件名为:hangge.js。内容如下:
//圆面积计算 export function area(radius) { return Math.PI * radius * radius; } //圆周长计算 export function circumference(radius) { return 2 * Math.PI * radius; }
(2)创建一个 main.js 文件,引入这个模块并调用。这里 import 命令使用大括号的形式加载模块对外的接口。
import {area,circumference} from './hangge'; console.log('圆面积:' + area(10)); console.log('圆周长:' + circumference(11));当然也可以使用星号(*)指定一个对象,实现模块的整体加载。
import * as circle from './hangge'; console.log('圆面积:' + circle.area(10)); console.log('圆周长:' + circle.circumference(11));

使用样例2:使用export default命令来输出模块
(1)下面我们使用 export default 命令用于指定模块的默认输出。模块文件名为:hangge.js。内容如下:
(2)创建一个 main.js 文件,引入这个模块并调用。注意:对于 export default 指定模块的默认输出,import 语句不需要使用大括号。
(3)同样借助 babel-node 来执行,运行结果如下:

//圆面积计算(作为默认接口) export default function(radius) { return Math.PI * radius * radius; } //圆周长计算 export function circumference(radius) { return 2 * Math.PI * radius; }
(2)创建一个 main.js 文件,引入这个模块并调用。注意:对于 export default 指定模块的默认输出,import 语句不需要使用大括号。
import area, {circumference} from './hangge'; console.log('圆面积:' + area(10)); console.log('圆周长:' + circumference(11));
(3)同样借助 babel-node 来执行,运行结果如下:

十三、Promises
Promises 是一种异步编程的方式,它应该是 ES6 中最重要的特性之一了。通过使用 promise,我们可以在完成一件事情后使用 then 来做另一件事。不再需要嵌套的回调方法了。可以有效地解决回调地狱(Callback Hell)等问题。
关于 Promises,可以参考我之前写的这几篇文章:
十四、模板字符串(Template Strings)
模板字符串提供了构建字符串的语法糖,类似于像 Perl,Python 等语言中的字符串插值。模板字符串通过反引号(`)和字符串插值(${})来实现。
1,创建基本的模板字符串
const name = "hangge", time = "today"; const info = `Hello ${name}, how are you ${time}?`; console.log(info);

2,多行字符串
const template = `<div class="view"> <input class="toggle" type="checkbox"> <label></label> <button class="destroy"></button> </div>`; console.log(template);可以看到所有的空格、缩进、换行都会被保留在输出之中:
