1.基础数据类型

新增了Symbol,BigInt。前者表示独一无二的值,用来定义对象的唯一属性名。后者可以表示任意大小的整数。

2.块级作用域

新增let,const关键字。前者声明的变量具有全局作用域,没有变量提升,有暂时性死区特性。后者声明常量,不能重新赋值。

3.解构赋值

更直观?

4.箭头函数

箭头函数不绑定this。this与上级通同。解决了匿名函数内存泄漏问题。

5.剩余参数

剩余参数配合解构赋值使用,能打印出参数来。

剩余参数可以将不定数量的参数表示为一个数组,方便声明不知道参数的函数。

6.函数优化

函数可以设置默认值。箭头函数。

7.map和reduce

前者接受一个函数,然后用这个函数去处理数组中的每一个元素后返回。

后者为数组中的每一个元素依次执行回调函数,不包括数组中被删除和未被赋值的元素。可选初始值,四个参数。

8.模块化

export和import。export用于规定模块的对外接口。import用于导入其它模块提供的功能。

9.对象,数组,字符串扩展

对象。获取所有key,value,二维,将多个src对象的值拷贝到dest中。

数组。find,findindex,include。

字符串。includes,startsWith,endswith

10.Promise

容器。保存着某个未来才会结束的事件。异步操作。可以从这个对象获取异步操作的消息。

then等异步操作结束做一些事情。catch失败后事件。

resolve,reject。异步成功后的回调函数和失败后的回调函数。

promise的精髓是状态,用维护状态传递状态的方式使回调函数能及时调用。

all提供了并行执行异步操作的能力,在所有异步操作执行完后才执行回调。all会把所有的异步结果放入一个数组中传给then。

race,跑的快的先

promise三种状态,等待,完成,失败。只能等待-完成或等待-失败。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// 先定义三个常量表示状态
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';

// 新建 MyPromise 类
class MyPromise {
constructor(executor){
// executor 是一个执行器,进入会立即执行
// 并传入resolve和reject方法
executor(this.resolve, this.reject)
}

// 储存状态的变量,初始值是 pending
status = PENDING;

// resolve和reject为什么要用箭头函数?
// 如果直接调用的话,普通函数this指向的是window或者undefined
// 用箭头函数就可以让this指向当前实例对象
// 成功之后的值
value = null;
// 失败之后的原因
reason = null;
// 存储成功回调函数
onFulfilledCallback = null;
// 存储失败回调函数
onRejectedCallback = null;

// 更改成功后的状态
resolve = (value) => {
// 只有状态是等待,才执行状态修改
if (this.status === PENDING) {
// 状态修改为成功
this.status = FULFILLED;
// 保存成功之后的值
this.value = value;
}
}

// 更改失败后的状态
reject = (reason) => {
// 只有状态是等待,才执行状态修改
if (this.status === PENDING) {
// 状态成功为失败
this.status = REJECTED;
// 保存失败后的原因
this.reason = reason;
}
}
}
then(onFulfilled, onRejected) {
// 判断状态
if (this.status === FULFILLED) {
// 调用成功回调,并且把值返回
onFulfilled(this.value);
} else if (this.status === REJECTED) {
// 调用失败回调,并且把原因返回
onRejected(this.reason);
} else if (this.status === PENDING) {
// ==== 新增 ====
// 因为不知道后面状态的变化情况,所以将成功回调和失败回调存储起来
// 等到执行成功失败函数的时候再传递
this.onFulfilledCallback = onFulfilled;
this.onRejectedCallback = onRejected;
}
}

// 更改成功后的状态
resolve = (value) => {
// 只有状态是等待,才执行状态修改
if (this.status === PENDING) {
// 状态修改为成功
this.status = FULFILLED;
// 保存成功之后的值
this.value = value;
// ==== 新增 ====
// 判断成功回调是否存在,如果存在就调用
this.onFulfilledCallback && this.onFulfilledCallback(value);
}
}

// 更改失败后的状态
reject = (reason) => {
// 只有状态是等待,才执行状态修改
if (this.status === PENDING) {
// 状态成功为失败
this.status = REJECTED;
// 保存失败后的原因
this.reason = reason;
// ==== 新增 ====
// 判断失败回调是否存在,如果存在就调用
this.onRejectedCallback && this.onRejectedCallback(reason)
}
}


module.exports = MyPromise

all

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Promise.myAll = (promises) => {
return new Promise((rs, rj) => {
// 计数器
let count = 0
// 存放结果
let result = []
const len = promises.length

if (len === 0) {
return rs([])
}

promises.forEach((p, i) => {
// 注意有的数组项有可能不是Promise,需要手动转化一下
Promise.resolve(p).then((res) => {
count += 1
// 收集每个Promise的返回值
result[ i ] = res
// 当所有的Promise都成功了,那么将返回的Promise结果设置为result
if (count === len) {
rs(result)
}
// 监听数组项中的Promise catch只要有一个失败,那么我们自己返回的Promise也会失败
}).catch(rj)
})
})
}