ES6手抄(阮一峰版)

还是推荐大家去看这个ECMAScript 6 入门

语法转化器

babel转码器,可以将ES6语法转化为ES5兼容的语法。

let、const

  1. let没有变量提升、不允许重复声明
  2. const声明一个只读常量,一旦声明,常量的值不能改变(const保证指向的那个内存地址不再改变)
  3. let、const声明的全局变量,不属于window
  4. ES6声明变量的6种方法:(ES5)var、function、(ES6)let、const、import、class

变量解构赋值

基本用法

  1. 数组解构赋值:let [temp,left,right] = [111,[],[]];
  2. 对象解构赋值:let {obj1 , obj2} = {obj1:"1111",obj2:"2222"}
  3. 字符串解构赋值:let [a,b,c,d,e]='hello'
  4. 函数参数的解构赋值:add([x, y])

用途

  1. 交换变量的值:[x,y] = [y,x]
  2. 从函数返回多个值:return[a,b,c]
  3. 函数参数的定义:f([1,2,3])
  4. 提取json数据let {errCode,errText} = {errCode:'200',errText:'success' }

数组的扩展

扩展运算符是…,好比rest参数的逆运算,将一个数组转化为用逗号分隔的参数序列。

1
2
3
4
console.log(...[1,2,3]);
//1,2,3
console.log(1,...[2,3,4],5);
//1,2,3,4,5

用于函数调用

1
2
3
4
5
6
7
8
function push(array,items){
array.push(...items);
}
function add(x,y){
return x+y;
}
const numbers = [3,38];
add(...numbers);

应用

复制数组

1
2
3
4
5
6
7
8
9
//es5
const a1 = [1, 2];
const a2 = a1.concat();
//es6
const a1 = [1, 2];
// 写法一
const a2 = [...a1];
// 写法二
const [...a2] = a1;

合并数组

1
2
3
4
//es5
[1,2].contact(more);
//es6
[1,2,...more];

将字符串转化为数组

1
2
[...'hello'];
// ["h", "e", "l", "l", "o"]

Array.from()

Array.from方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map)。

1
2
3
4
5
6
7
8
//数组去重
var array = [1, 2, 1, 1, '1'];

function unique(array) {
return Array.from(new Set(array));
}

console.log(unique(array)); // [1, 2, "1"]

数组实例的includes()

Array.prototype.includes方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes方法类似。ES2016 引入了该方法。

1
2
3
[1, 2, 3].includes(2)     // true
[1, 2, 3].includes(4) // false
[1, 2, NaN].includes(NaN) // true

新数据类型:Symbol

ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,前六种是:undefinednull、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。

Symbol 值通过Symbol函数生成。这就是说,对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的 Symbol 类型。凡是属性名属于 Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。

1
2
3
let s = Symbol();
typeof s
// "symbol"

promise

更详细介绍promise

Promise对象有以下两个特点。

(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。

(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

1
2
3
4
5
6
7
8
9
const promise = new Promise(function(resolve, reject) {
// ... some code

if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});

generator

更详细介绍generator

Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同。本章详细介绍 Generator 函数的语法和 API,它的异步编程应用请看《Generator 函数的异步应用》一章。

Generator 函数有多种理解角度。语法上,首先可以把它理解成,Generator 函数是一个状态机,封装了多个内部状态。

执行 Generator 函数会返回一个遍历器对象,也就是说,Generator 函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。

形式上,Generator 函数是一个普通函数,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式,定义不同的内部状态(yield在英语里的意思就是“产出”)。

yield表达式是暂停执行的标记,而next方法可以恢复执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function* helloWorldGenerator() {
yield 'hello';
yield 'world';
return 'ending';
}

var hw = helloWorldGenerator();

hw.next()
// { value: 'hello', done: false }

hw.next()
// { value: 'world', done: false }

hw.next()
// { value: 'ending', done: true }

hw.next()
// { value: undefined, done: true }

总结一下,调用 Generator 函数,返回一个遍历器对象,代表 Generator 函数的内部指针。以后,每次调用遍历器对象的next方法,就会返回一个有着valuedone两个属性的对象。value属性表示当前的内部状态的值,是yield表达式后面那个表达式的值;done属性是一个布尔值,表示是否遍历结束。

async

更详细介绍async

ES2017 标准引入了 async 函数,使得异步操作变得更加方便。

async 函数是什么?一句话,它就是 Generator 函数的语法糖。

前文有一个 Generator 函数,依次读取两个文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const fs = require('fs');

const readFile = function (fileName) {
return new Promise(function (resolve, reject) {
fs.readFile(fileName, function(error, data) {
if (error) return reject(error);
resolve(data);
});
});
};

const gen = function* () {
const f1 = yield readFile('/etc/fstab');
const f2 = yield readFile('/etc/shells');
console.log(f1.toString());
console.log(f2.toString());
};

写成async函数,就是下面这样。

1
2
3
4
5
6
const asyncReadFile = async function () {
const f1 = await readFile('/etc/fstab');
const f2 = await readFile('/etc/shells');
console.log(f1.toString());
console.log(f2.toString());
};

一比较就会发现,async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await,仅此而已。async函数对 Generator 函数的改进,体现在以下四点。

  1. 内置执行器。

    Generator 函数的执行必须靠执行器,所以才有了co模块,而async函数自带执行器。也就是说,async函数的执行,与普通函数一模一样,只要一行。

  2. 更好的语义。

  3. 更广的适用性。

  4. 返回值是 Promise。