Set和Map数据结构 const s = new Set(); [2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x)); for (let i of s) { console.log(i); } // 2 3 5 4const a = [[1, 2], [3, 4]]; const ws = new WeakSet(a); // WeakSet {[1, 2], [3, 4]} let map = new Map(); map.set(‘foo’, true); map.get(‘foo’); map.size // 2 map.clear() map.size // 0
新增的运算符 模板字符串 “、对象中的扩展运算符(…)用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中、**指数运算符
Proxy和Reflect
Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程。(C++重载运算符) Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。 Reflect对象与Proxy对象一样,也是 ES6 为了操作对象而提供的新 API。Reflect对象的设计目的有这样几个。(1) 将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上。现阶段,某些方法同时在Object和Reflect对象上部署,未来的新方法将只部署在Reflect对象上。也就是说,从Reflect对象上可以拿到语言内部的方法。(2) 修改某些Object方法的返回结果,让其变得更合理。比如,Object.defineProperty(obj, name, desc)在无法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc)则会返回false。
Promise const promise = new Promise(function(resolve, reject) { // … some code if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
} }); promise.then(function(value) { // success }, function(error) { // failure });getJSON(‘/posts.json’).then(function(posts) { // … }).catch(function(error) { // 处理 getJSON 和 前一个回调函数运行时发生的错误 console.log(‘发生错误!’, error); }); promise .then(result => {···}) .catch(error => {···}) .finally(() => {···}); const p = Promise.race([p1, p2, p3]); const p = Promise.race([ fetch(‘/resource-that-may-take-a-while’), new Promise(function (resolve, reject) {
setTimeout(() => reject(new Error('request timeout')), 5000)
}) ]); p.then(console.log).catch(console.error);
Generator Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同。本章详细介绍 Generator 函数的语法和 API,它的异步编程应用请看《Generator 函数的异步应用》一章。
Generator 函数有多种理解角度。语法上,首先可以把它理解成,Generator 函数是一个状态机,封装了多个内部状态。
执行 Generator 函数会返回一个遍历器对象,也就是说,Generator 函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。
形式上,Generator 函数是一个普通函数,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式,定义不同的内部状态(yield在英语里的意思就是“产出”)。
function* helloWorldGenerator() { yield ‘hello’; yield ‘world’; return ‘ending’; } var hw = helloWorldGenerator();
上面代码定义了一个 Generator 函数helloWorldGenerator,它内部有两个yield表达式(hello和world),即该函数有三个状态:hello,world 和 return 语句(结束执行)。
然后,Generator 函数的调用方法与普通函数一样,也是在函数名后面加上一对圆括号。不同的是,调用 Generator 函数后,该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象,也就是上一章介绍的遍历器对象(Iterator Object)。
下一步,必须调用遍历器对象的next方法,使得指针移向下一个状态。也就是说,每次调用next方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield表达式(或return语句)为止。换言之,Generator 函数是分段执行的,yield表达式是暂停执行的标记,而next方法可以恢复执行。
上面代码一共调用了四次next方法。
第一次调用,Generator 函数开始执行,直到遇到第一个yield表达式为止。next方法返回一个对象,它的value属性就是当前yield表达式的值hello,done属性的值false,表示遍历还没有结束。
第二次调用,Generator 函数从上次yield表达式停下的地方,一直执行到下一个yield表达式。next方法返回的对象的value属性就是当前yield表达式的值world,done属性的值false,表示遍历还没有结束。
第三次调用,Generator 函数从上次yield表达式停下的地方,一直执行到return语句(如果没有return语句,就执行到函数结束)。next方法返回的对象的value属性,就是紧跟在return语句后面的表达式的值(如果没有return语句,则value属性的值为undefined),done属性的值true,表示遍历已经结束。
第四次调用,此时 Generator 函数已经运行完毕,next方法返回对象的value属性为undefined,done属性为true。以后再调用next方法,返回的都是这个值。
总结一下,调用 Generator 函数,返回一个遍历器对象,代表 Generator 函数的内部指针。以后,每次调用遍历器对象的next方法,就会返回一个有着value和done两个属性的对象。value属性表示当前的内部状态的值,是yield表达式后面那个表达式的值;done属性是一个布尔值,表示是否遍历结束。
yield 表达式 由于 Generator 函数返回的遍历器对象,只有调用next方法才会遍历下一个内部状态,所以其实提供了一种可以暂停执行的函数。yield表达式就是暂停标志。
遍历器对象的next方法的运行逻辑如下。
(1)遇到yield表达式,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。
(2)下一次调用next方法时,再继续往下执行,直到遇到下一个yield表达式。
(3)如果没有再遇到新的yield表达式,就一直运行到函数结束,直到return语句为止,并将return语句后面的表达式的值,作为返回的对象的value属性值。
(4)如果该函数没有return语句,则返回的对象的value属性值为undefined。
初识ES6的模块 <script src=”main.js“ type=”module“></script> //引入模块 import {foo} from ”./a.js“; console.log(foo); window.foo=foo; //定义模块 var foo={a:1}; export { foo };
总结:较为流行的好像是使用webpack等工具。
import defaultExport from ”module-name“; import * as name from ”module-name“; import { export } from ”module-name“; import { export as alias } from ”module-name“; import { export1 , export2 } from ”module-name“; import { foo , bar } from ”module-name/path/to/specific/un-exported/file“; import { export1 , export2 as alias2 , […] } from ”module-name“; import defaultExport, { export [ , […] ] } from ”module-name“; import defaultExport, * as name from ”module-name“; import ”module-name“; var promise = import(”module-name“);//这是一个处于第三阶段的提案。
async和await async函数是使用async关键字声明的函数。 async函数是AsyncFunction构造函数的实例, 并且其中允许使用await关键字。async和await关键字让我们可以用一种更简洁的方式写出基于Promise的异步行为,而无需刻意地链式调用promise。返回值是一个promise对象
function* demo(){} //异步函数,内部可以使用await
await 操作符用于等待一个Promise 对象。它只能在异步函数 async function 中使用。
[返回值] = await 表达式;
表达式为一个 Promise 对象或者任何要等待的值。
返回值返回 Promise 对象的处理结果。如果等待的不是 Promise 对象,则返回该值本身。
await 表达式会暂停当前 async function 的执行,等待 Promise 处理完成。若 Promise 正常处理(fulfilled),其回调的resolve函数参数作为 await 表达式的值,继续执行 async function。
若 Promise 处理异常(rejected),await 表达式会把 Promise 的异常原因抛出。
async+await=generator,不同于generator的是前者会自动等待后运行,生成器需要指定。
总结
弄清操作是异步还是同步操作。异步操作不会阻塞程序,而是直接向后执行。 实例化的Promise会立即送入消息队列执行等待执行,一般称Promise执行器。 x => x * x、()=>a*a,JS箭头函数的多种写法。
给编程语言编程 Object.defineProperty(Obj,Attr,Config),给一个对象定义一个属性,并设置属性的配置属性。达到vb中属性函数(Property get 、set)的类似功能。
ES6中export及export default的区别
在JavaScript ES6中,export与export default均可用于导出常量、函数、文件、模块等,你可以在其它文件或模块中通过import+(常量 | 函数 | 文件 | 模块)名的方式,将其导入,以便能够对其进行使用,但在一个文件或模块中,export、import可以有多个,export default仅有一个。 1.export与export default均可用于导出常量、函数、文件、模块等 2.在一个文件或模块中,export 、import可以有多个,export default仅有一个 3.通过export方式导出,在导入时要加{ },export default则不需要 4.export能直接导出变量表达式,export default不行