Nuke 与 QAP get started 文档

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

更多arrow function

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

[DB/OL] Overview of ECMAScript 6 features