展开(三点)运算符、剩余参数(实现无限平铺)、可选链、空值合并

78 阅读2分钟
1. 展开(三点)运算符
  • 进行数组合并
let arr = [1,2,3];
let arr3 = [0, ...arr, 9];
console.log(arr3) // [0,1,2,3,9]

以上代码等同于

let arr2 = [0].concat(arr);
console.log(arr2); // [0,1,2,3,9]
  • 构造字面量对象(需要注意展开运算符是 浅拷贝)
let obj = { name: 'Green', age: 36 };
let person1 = {
  ...obj,
  gender: '男'
}
let person2 = {
  ...obj,
  gender: '女'
}
console.log(person1, person2);

打印的person1, person2

image.png

  • 属性覆盖 在...obj之后重新赋值name,name:'金渡
let person3 = {
  ...obj,
  gender:'女',
  name:'金渡',  
}
console.log(person3);

打印的person3

image.png

2. 剩余参数
  • 是一个数组
  • 具有数组的方法,不是伪数组
function add(...args) {
  console.log('是否是伪数组', args.reduce); // 具有数组的方法,不是伪数组
  console.log(args); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 90]
  return args.reduce((sum, n) => {
    return sum + n;
  }, 0)
}
const { log: l } = console;
// 不限制参数个数
l(add(1, 2, 3, 4, 5, 6, 7, 8, 9, 90)) // 135
  • 可以接收到剩余的参数
  • args等同于取第二个以后的参数
  • args等同于Array.prototype.slice.call(argument, 2)
function ff(a, b, ...args) {
  console.log(args) // [3,4,5,6]
}

ff(1, 2, 3, 4, 5, 6);
  • 实现无限平铺
  • 方法1:使用arr.flat()方法,给其传参数Infinity(即平铺无限次)
let arr = [1, [2, [3, [6, [7]]]], 4, 5];
let newArr = arr.flat(Infinity);
console.log(newArr); // [1,2,3,6,7,4,5]
  • 方法2:while循环结合some方法判断是否有元素是数组,如果有数组就进行平铺
  • 平铺方法为[].concat(...arr)
function myFlat(arr) {
  //判断是否有元素是数组,循环结束
  while (arr.some((ele) => {
    return Array.isArray(ele)
  })) {
    // 平铺元素
    arr = [].concat(...arr)
  }

  return arr;
}
const newArr2 = myFlat(arr2);
console.log(newArr2)

以上代码的while部分可以简写为:

while (arr.some(Array.isArray)) {
  // 平铺元素
  arr = [].concat(...arr)
}
3.可选链
  • 判断获取的数据是否存在

先来一段模拟一段获取res的代码

// 正常能获取到的值
let res = {
  code: 200,
  msg: 'success',
  data: {
    info: [
      0, 1, 2, 3,
      {
        obj: { id: 88 },
        arr: [{ name: 2 }]
      }
    ]
  }
}
// 网络出现异常
if (Math.random() > 0.7) {
  res = { data: null }
}

不使用可选链时,要想避免数据获取不到时报错白屏的代码写法:

let id = res && res.data && res.data.info && res.data.info[4]
  && res.data.info[4].obj && res.data.info[4].obj.id;

可选链的写法:

let id2 = res?.[data]?.info?.[4]?.obj?.id;
  • 也可以实现可选链函数
function errorHandler2(fn) {
  console.log('错误处理')
  fn?.('回调信息'); // 可选链函数

}
errorHandler2(); // 不执行
errorHandler2(undefined);// 不执行
errorHandler2(null);// 不执行
errorHandler2((info) => {
  console.log('回调执行') // 回调执行
});
4. 空值合并
  • 进行默认数据的填充, 区分隐式数据转换(针对null 和 undefined)
  • !!可以理解为去非再取非
let n1 = 0, n2 = 1;
let s1 = '', s2 = 'a';

console.log(!!n1, !!n2) // false true
console.log(!!s1, !!s2) // false true
console.log(!!{}, !!null) // true false

let val = n1 || '后者';
let val2 = s1 || '后者2';
console.log(val) // 后者
console.log(val2) // 后者2
  • 空值合并 null 和 undefined
let val3 = null ?? '后者3'
let val4 = undefined ?? '后者4'
let val5 = 0 ?? '后者5'; // 空值合并运算,不会吧0转换为false

console.log(val3, val4, val5) // 后者3 后者4 0