扩展运算符

187 阅读4分钟

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);
});