3.1 ECMAScript 6
目前QAP只支持使用ES6(ECMAScript 6)语法进行开发。本文仅仅列举了ES6的新增语法的简单描述,适合不太熟悉的ES6语法的开发者, 并在结尾列出了参考文献。开发者可以参考参考文献查看更多详情。
let
ES6新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。
'use strict'
{
var date = new Date();
let time = date.getTime();
}
console.log(date); //Wed Sep 21 2016 10:46:35 GMT+0800 (CST)
console.log(time); //ReferenceError: time is not defined
赋值
ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
var [a, b, c] = [1, 2, 3];
解构赋值允许指定默认值。
var [foo = true] = [];
foo // true
解构不仅可以用于数组,还可以用于对象。
var { foo, bar } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"
集合(Set)
ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。Set本身是一个构造函数,用来生成Set数据结构。
var s = new Set();
[1, 3, 5, 5, 3, 1].map(x => s.add(x));
for (let i of s) {
console.log(i);//1, 3, 5
}
箭头语法(Arrows)
ES6新增的箭头函数和java 8、C#和CoffeeScript的特性类似,允许开发者使用=>
达到类似于匿名函数的功能。
[1,2,3].forEach(v => {
console.log(v)
});
需要额外注意的是,箭头函数和匿名函数的区别是,箭头函数可以类似于外围的代码一样使用this。
var bob = {
_name: 'Bob',
_friends: ['jack', 'tom'],
printFriends() {
this._friends.forEach(f =>
console.log(this._name + " knows " + f));
}
}
bob.printFriends();
//Bob knows jack
//Bob knows tom
Promise
Promise是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6将其写进了语言标准,统一了用法,原生提供了Promise对象。
var promise = new Promise(function(resolve, reject) {
// ... some stuff
if (true/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
Promise实例生成以后,可以用then方法分别指定Resolved状态和Reject状态的回调函数。
promise.then(function(value) {
// success
}, function(error) {
// failure
});
示例:
function delay(time){
return new Promise((resolve, reject) => {
setTimeout(resolve, time, new Object());
//或者
/*
setTimeout(function(){
resolve(new Object());
}, time)
*/
});
}
delay(2000).then((value) => {
console.log(value);//两秒之后输出 Object {}
});
类(Classes)
使用ES6引入了classes的语法糖(内部基于prototype实现的面向对象设计模式)。使用该语法糖很方便的创建对象、继承(prototype-based inheritance)。
类声明(Class declarations)
定义一个class,需要用到关键字class
:
'use strict'
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
console.log(new Point(1,2)) //Point { x: 1, y: 2 }
跟函数声明不同的是,class的声明需要在使用前。
'use strict'
var func = myfunc() //不会报错
function myfunc(){
}
var myClass = new MyClass();//报错:MyClass is not defined
class MyClass{
}
另一个定义类的方式叫做 类表达式。它与函数表达式的运行方式完全一样。一个类表达式可以是具名的也可以是匿名的。
'use strict'
// unnamed
var Polygon = class {
constructor(x, y) {
this.x = x;
this.y = y;
}
};
// named
var Polygon = class PolygonClass {
constructor(x, y) {
this.x = x;
this.y = y;
}
};
函数定义(Method definitions)
在ES5中,以前的写法可能是:
var obj = {
foo: function() {},
bar: function() {}
};
ES6中则可以这样:
var obj = {
foo() {},
bar() {}
};
ES6同样使用ES5的getter和setter语法:
'use strict'
class Rect {
constructor(width, height) {
this.width = width
this.height = height
}
get area(){
return this.width * this.height
}
set wid (w){
this.width = w
}
};
var myRect = new Rect(2, 4)
myRect.wid = 1
console.log(myRect.area) //4
静态方法(Static methods)
static关键字是ES6的另一个语法糖,它使静态方法声明也成为了一个一等公民。在ES5中,静态方法就像是构造函数的一个属性。ES5
写法:
function Point() {
// ...
}
Point.compare = function(a, b) {
// ...
}
使用了ES6
之后,你可以:
class Point {
static compare(a, b) {
// ...
}
}
继承(Sub classing with extends)
类似于JAVA,使用extends关键字实现类的继承。
'use strict'
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Dog extends Animal {
speak() {
console.log(this.name + ' barks.');
}
}
new Dog('dog').speak();//dog barks.
点击查看详情
模块(Modules)
在ES6之前,社区制定了一些模块加载方案,最主要的有CommonJS和AMD两种。前者用于服务器,后者用于浏览器。ES6在语言规格的层面上,实现了模块功能,而且实现得相当简单,完全可以取代现有的CommonJS和AMD规范,成为浏览器和服务器通用的模块解决方案。
// lib/math.js
export function sum(x, y) {
return x + y;
}
export var pi = 3.141593;
// app.js
import * as math from "lib/math";
alert("2π = " + math.sum(math.pi, math.pi));
或者这样使用:
// otherApp.js
import {sum, pi} from "lib/math";
alert("2π = " + sum(pi, pi));
参考文献:
阮一峰.ECMAScript 6入门[M].北京:电子工业出版社,2014-08-01