1、扩展运算符
1)、合并数组
let arr1 = [1, 2, 3, 4]
let arr2 = [5, 6, 7, 8]
arr1.push(...arr2) // 将arr2 追加到数组的末尾
arr1.unshift(...arr2) // 将arr2 追加到数组的开头
将数组放在特定位置上:
let arr1 = ['two', 'three'];
let arr2 = ['one', ...arr1, 'four', 'five'];
// ["one", "two", "three", "four", "five"]
扩展:合并两个数组并去重
set:类似于数组,但是成员的值都是唯一的,没有重复的值
let arr1 = ['one', 'two', 'three'];
let arr2 = ['two', 'three', 'four', 'five'];
arr1.push(...arr2)
Array.from(...new Set(arr1))
// ['one', 'two', 'three', 'four', 'five']
2)、复制数组
let arr1 = ['one', 'two', 'three'];
let arr2 = [...arr1];
3)、替代数组的 apply 方法
// ES5 的写法
function f(x, y, z) {
// ...
}
var args = [0, 1, 2];
f.apply(null, args);
// ES6 的写法
function f(x, y, z) {
// ...
}
var args = [0, 1, 2];
f(...args);
求最大值:
// ES5 的写法
Math.max.apply(null, [14, 3, 77])
// ES6 的写法
Math.max(...[14, 3, 77])
// 等同于
Math.max(14, 3, 77);
4)、解构赋值
// 获取数组第一个元素,剩余元素组成一个数组
// ES5
a = list[0], rest = list.slice(1)
// ES6
[a, ...rest] = list
// 其他例子:
const [first, ...rest] = [1, 2, 3, 4, 5];
first // 1
rest // [2, 3, 4, 5]
const [first, ...rest] = [];
first // undefined
rest // []:
const [first, ...rest] = ["foo"];
first // "foo"
rest // []
// 将字符串转成数组
[...'hello']
// [ "h", "e", "l", "l", "o" ]
5)、对象
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x // 1
y // 2
z // { a: 3, b: 4 }
// 由于结构赋值要求等号右边是一个对象,所以如果等号右边是undefined或null,就会报错,因为它们无法转为对象。
let {x ,y ,...z} = null;//运行时报错
let {x ,y ,...z} = undefined;//运行时报错
// 解构赋值必须是最后一个参数,否则也会报错。
let { ...x, y, z } = obj; // 句法错误
let { x, ...y, ...z } = obj; // 句法错误
// 变量x是单纯的解构赋值,所以可以读取对象o继承的属性;变量y和z是双重解构赋值,只能读取对象自身的属性,所以只有变量z可以赋值成功
const o = Object.create({x:1,y:2});
o.z = 3;
let {x,...{y,z}} = o;
x//1
y//undefined
z//3
6)、合并对象
let ab = {...a,...b};
//等同于
let ab = Object.assign({},a,b);
2、promise
promise为构造函数。

1)、promise.all
Promise.all可以将多个Promise实例包装成一个新的Promise实例。同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值。
const p = Promise.all([p1, p2, p3]);
p的状态由p1、p2、p3决定,分成两种情况。
(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
(2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。
let p1 = new Promise((resolve, reject) => {
resolve('成功了')
})
let p2 = new Promise((resolve, reject) => {
resolve('success')
})
let p3 = new Promise((resolve, reject) => {
reject('失败')
})
Promise.all([p1, p2]).then((result) => {
console.log(result) //['成功了', 'success']
}).catch((error) => {
console.log(error)
})
Promise.all([p1,p3,p2]).then((result) => {
console.log(result)
}).catch((error) => {
console.log(error) // 失败了,打出 '失败'
})
Promise.all获得的成功结果的数组里面的数据顺序和Promise.all接收到的数组顺序是一致的,即p1的结果在前,即便p1的结果获取的比p2要晚。这带来了一个绝大的好处:在前端开发请求数据的过程中,偶尔会遇到发送多个请求并根据请求顺序获取和使用数据的场景,使用Promise.all毫无疑问可以解决这个问题。
let wake = (time) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`${time / 1000}秒后醒来`)
}, time)
})
}
let p1 = wake(3000)
let p2 = wake(2000)
Promise.all([p1, p2]).then((result) => {
console.log(result) // [ '3秒后醒来', '2秒后醒来' ]
}).catch((error) => {
console.log(error)
})
2)、promise.race
Promse.race就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success')
},1000)
})
let p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('failed')
}, 500)
})
Promise.race([p1, p2]).then((result) => {
console.log(result)
}).catch((error) => {
console.log(error) // 打开的是 'failed'
})
可以用race给某个异步请求设置超时时间,并且在超时后执行相应的操作,代码如下:
//请求某个图片资源
function requestImg(){
var p = new Promise(function(resolve, reject){
var img = new Image();
img.onload = function(){
resolve(img);
}
img.src = 'xxxxxx';
});
return p;
}
//延时函数,用于给请求计时
function timeout(){
var p = new Promise(function(resolve, reject){
setTimeout(function(){
reject('图片请求超时');
}, 5000);
});
return p;
}
Promise
.race([requestImg(), timeout()])
.then(function(results){
console.log(results);
})
.catch(function(reason){
console.log(reason);
});