ECMAScript 6
Part1
- let与const声明变量,
作用域有所不同 - 变量解构赋值,
不规则格式一一智能对应赋值 - 字符串扩展,
扩充长度、
嵌入变量、
嵌入js表达式、
嵌入并调用函数返回值、
标签模板(过滤注入攻击) - 正则扩展,
RegExp对象,
几种模式匹配(i,g,y,s,)、
先行断言、
后行断言 - 数值扩展,
数据检测、
原全局类型转换下挂到Number对象、
Math对象扩展(判断数值正负整数、对数、三角函数、指数、Integer类型大数值(不能与Number混算)) - 函数扩展,
添加函数参数默认值(通过省略参数或者传入undefined触发,定义域与全局平级与函数内部互相独立)、
...rest参数、
箭头函数(没有自己的this==>引用外层的this,函数内使用this不需绑定bind;不能用call()、apply()、bind()这些方法去改变this的指向;不能用yield)、
尾调用==>优化、
尾递归==>节省内存(只保留一个调用记录,复杂度 O(1) )、
使用函数参数默认值实现单参数单帧递归 - 数组扩展,
...运算符,拆解数组==>参数序列(rest的逆运算)、
Array.from()对象转数组、可遍历对象转数组(迭代器接口、Map、Set)、
遍历方法 entries()遍历键值对,keys(),values() - 对象扩展,
方法的简写,类似java类声明方法、
get与set函数、
对象比较(is)、对象合并(assign,是浅拷贝,对象属性为对象则仅引用对象)、
Part2
Set与Map
Set:无序元素,元素不能重复,遍历顺序就是插入顺序,查找效率更高,而Array元素可重复;
weakSet:weakSet的成员只能是对象;引用对象在外部消失,它在 WeakMap 里面的引用就会自动消失 ==> 释放内存;
Map:值值对;与对象的区别就是,可以用对象、数组作为键名;遍历顺序就是插入顺序;
weakMap: 只接受对象作为键名;键名所引用的对象都是弱引用,即垃圾回收机制不将该引用考虑在内。因此,只要所引用的对象的其他引用都被清除,垃圾回收机制就会释放该对象所占用的内存。
垃圾回收机制
垃圾回收机制依赖引用计数,如果一个值的引用次数不为0,垃圾回收机制就不会释放这块内存。对于那些不重要的引用,在结束使用之后,有时会忘记取消引用,导致内存无法释放,进而可能会引发内存泄漏。
Proxy
var proxy = new Proxy(所要拦截的目标对象target, 定制拦截行为handler);
对目标对象,设置一个隔离层,经过proxy-handler验证才能实现对应操作。
Proxy.revocable方法返回一个可取消的 Proxy 实例。回收代理权,不允许再次访问;
设置了proxy代理的对象,在proxy内部的this都指向proxy,而不是target;需要使用bind(target);
Reflect
Reflect对象存放语言内部方法;
让Object命令式操作都变成函数行为,封装命令;
实现观察者模式==>监听;
Promise
promise
是异步操作的预定义,预定义了成功(Resovled)与失败(Rejected)的后续执行内容。使多层嵌套的回调函数能够有美观的格式,形同同步执行,实为异步执行。
var p1 = new Promise(function (resolve, reject) {
// ...
});
var p2 = new Promise(function (resolve, reject) {
// ...
resolve(p1); // 返回另一个异步操作
})
上面代码中,p1和p2都是Promise的实例,但是p2的resolve方法将p1作为参数,即一个异步操作的结果是返回另一个异步操作。
注意,这时p1的状态就会传递给p2,也就是说,p1的状态决定了p2的状态。如果p1的状态是Pending,那么p2的回调函数就会等待p1的状态改变;如果p1的状态已经是Resolved或者Rejected,那么p2的回调函数将会立刻执行。
promise
Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
var p = Promise.all([p1, p2, p3]);
p的状态由p1、p2、p3决定,分成两种情况。
(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
(2)任何一个被rejected,p的状态就变成rejected,返回第一个被reject的实例的返回值;
promise.resolve
Promise.resolve() 将现有对象转为Promise对象
有效的自定义方法
done
提供一个处于回调链的尾端的done方法,保证在then或catch中的跑出的错误都能被接到;
finally
无论Promise对象最后状态如何,是resolved还是rejected,都会执行的一个操作(eg.运行结束前关闭服务器)。
promise.try 处理异常
iterator 迭代器
通过Symbol.iterator对数据结构进行有序遍历
generator 生成器
具有状态的函数;拥有众多返回值;实际使用与iterator结合
function* foo(x, y) { ··· }
async 是generator函数定义的语法糖,封装了generator函数与自动执行器
Generator 函数的星号(*)替换成async;
将yield替换成await
改进之处:
- 不必再用co模块;调用方法与普通函数相同
- 语法美观;
- yield的命令后跟内容,种类比co模块多; 可以是Promise对象(含有异步)和原始类型的值(类似同步)
- 返回promise对象
async 标识符定义generator函数,即async函数,使用await表示调用内含异步操作的函数;调用这个async函数,立即就会返回一个promise对象(本身写了return Promise就返回这个promise;不然就把函数语句封装成一个promise),在promise对象获得resolve指令之后,才继续执行await语句的下一个语句;如果promise变为reject,则整个async函数就中断执行
async函数的使用:可以后接then(),async函数的内部return值会成为then方法的回调函数参数
为了使async函数中的多个await,在前几个await出错变为reject的情况下,仍能执行,把会出错的await放进try...catch块中,接住错误即可;
let foo = await getFoo();
let bar = await getBar();
两个独立的一步操作,按照上述写法会造成阻塞;改为同时触发写法
// 写法一 并发执行
let [foo, bar] = await Promise.all([getFoo(), getBar()]);
// 写法二
let fooPromise = getFoo();
let barPromise = getBar();
let foo = await fooPromise;
let bar = await barPromise;
async的异步遍历器
Symbol.asyncIterator属性,在调用next方法时,返回promise对象;因此.next()可以链式调用.then();
Symbol.iterator属性,在调用next方法是,返回yield对象;
异步generator函数
异步 Generator 函数,执行后返回一个异步 Iterator 对象。对该对象调用next方法,返回一个 Promise 对象。
async function* gen() {
yield 'hello';
}
const genObj = gen(); // genObj是一个异步迭代器对象;
genObj.next().then(x => console.log(x)); // next()返回Promise对象,可后跟then或catch
// { value: 'hello', done: false }
class
class 是 对象的更符合程序设计的写法;本质上并没有区别
类的所有方法都定义在类的prototype属性上面。
class B {}
let b = new B();
b.constructor === B.prototype.constructor // true
静态方法 static 不会被继承
静态属性 static 不会被继承