Javascript ES6 笔记

for-of

for-of通过迭代器遍历各种集合,for-in遍历对象属性

迭代器

对象通过[Symbol.iterator]()方法指定它的迭代器,迭代器是实现了.next()方法的对象,.next()方法的返回值形如{done: false, value: xxx}

迭代器贯穿ES6的始终,它是数据和循环的新标准。

生成器

生成器函数用function*声明。生成器函数内部的yield类似return,区别是只能return一次却可以yield多次。生成器执行时遇到yield就暂停,后续可恢复执行状态。

当你调用生成器函数时,它并不立即执行,而是返回一个暂停在函数入口的迭代器。当你调用迭代器的.next()方法时,函数恢复执行,直到下一个yield后再暂停。

.next()方法接受一个可选参数,该参数在稍后函数恢复执行时会代替yield表达式的返回值

生成器是迭代器。所有的生成器都有内建[Symbol.iterator]()和.next()方法的实现。你只须编写循环部分的行为。

使对象可遍历:通过[Symbol.iterator]()方法指定对象的迭代器为生成器函数,编写这个生成器函数来yield这个对象的每一个值。

当你面对一个复杂的循环时,你可以拆分出生成数据的代码,将其转换为独立的生成器函数,然后使用for (let data of myNewGenerator(args))遍历我们所需的数据。

yield只能生成一个值;yield*可以后接迭代器,一次次直到遍历该迭代器的所有值

可用yield*在生成器中调用生成器

字符串模板

模板用 `(反撇号)括起来,字符串插值形如${user.name}

标签模板,在模板字符串开始的反撇号前加一个额外的标签

1
var message = SaferHTML`<p>${bonk.sender} 向你示好。</p>`;
上面代码等效于
1
var message = SaferHTML(templateData, bonk.sender);
templateData是一个不可变数组,存储着模板所有的字符串部分。

不定参数和默认参数

1
function containsAll(haystack, ...needles)
1
function animalSentence(animals2="tigers", animals3="bears")

默认值表达式自左向右求值,这意味着,后面的赋值式可以使用前面的刚赋了值的参数

没有默认值的参数隐式默认为undefined

传递undefined值等效于不传值

解构赋值

数组解构

1
[ variable1, variable2, ..., variableN ] = array;

如果你想在赋值的同时声明变量,可在赋值语句前加入var、let或const关键字,如:

1
const [foo, [[bar], baz]] = [1, [[2], 3]];
可以在对应位留空来跳过被解构数组中的某些元素:
1
var [,,third] = ["foo", "bar", "baz"];
可以通过“不定参数”模式捕获数组中的所有尾随元素:
1
var [head, ...tail] = [1, 2, 3, 4];
1
log(...array); // log所有值
当访问空数组或越界访问数组时,对其解构与对其索引的结果都是:undefined
1
2
[][0] //undefined
var [missing] = []; //undefined
数组解构赋值的模式同样适用于任意迭代器:
1
2
function* fibs() { … }
var[first,second,third] = fibs();

对象解构

首先指定属性,然后指定变量:

1
var{name:nameA}={name:"Bender"}; // nameA
当属性名与变量名一致时可简写:
1
var { foo, bar } = { foo: "lorem", bar: "ipsum" };
解构对象时若赋值语句前没有let、const或var关键字,要将整个表达式用一对小括号包裹(防止js引擎将任何以{开始的语句解析为块语句):
1
({ blowUp } = { blowUp: 10 });
当你要解构的属性未定义时你可以提供一个默认值:
1
2
var [missing = true] = [];
var { message: msg = "Something went wrong" } = {}; // msg

箭头函数

只有一个参数时,形如:arg => expr

多个参数(或无参数、不定参数、默认参数、参数解构)时,要用小括号包裹参数:

1
var total = values.reduce((a, b) => a + b, 0);
返回的对象字面量要包裹在小括号里:
1
var chewToys = puppies.map(puppy => ({}));

符号

1
let isMoving = Symbol(“the description");

symbol不能被自动转换为字符串,要通过String(sym)sym.toString()显式转换

获取symbol: * Symbol() // 新建symbol * Symbol.for(key) // 共享symbol * 少许几个自带的symbol,如Symbol.iterator

集合

Map或Set的遍历顺序就是其中元素的插入顺序

WeakMap或WeakSet都不可遍历

代理

有形如obj.[[xxx]]()的14个内部方法

1
var proxy = new Proxy(target, handler)
handler对象所含的方法将对应重写proxy的内部方法,没被重写的proxy方法调用会转发到target上执行

let和const

let就是新的var,块级作用域,for循环的每次迭代绑定新的let变量(不像原来的所有迭代都绑定同一个var变量)

const声明常量

模块

一个文件就是一个模块

导出:

1
2
3
4
export {detectCats, Kittydar};
export { v1 as streamV1, v2 as streamV2 };
export default { field1: value1, field2: value2 };
export {Tea, Cinnamon} from "sri-lanka";
或直接在function、class、let/const/var的声明前加export关键字

导入:

1
2
3
4
import {detectCats, Kittydar} from "kittydar.js";
import {flip as flipOmelet} from "eggs.js";
import _ from "lodash"; // 导入default
import * as cows from “cows”;

ES7

Async函数和生成器类似,但特定于异步编程。调用generator返回iterator,调用async函数则返回promise。generator使用yield来暂停并生成值,async函数则使用await来暂停并等着promise。

参考