合理使用ES6 ... 让代码优雅一点吧

发布时间:2024年01月03日
前言

在写代码时常常会使用...xx这种用法,有时叫它展开运算符,有时又叫剩余参数运算符,感觉有点乱,究其原因是自己理解不够清晰,下面简单记录一下🐳

一、 ...的两种含义

image-20230130170344620

1. 剩余参数运算符
  • 定义函数的时候使用运算符(...),会将传过来的多余参数合到一起

  • 剩余参数永远是个数组,即使没有值,也是空数组

  • 剩余参数只能作为最后一个参数

const fn = (num1, num2, ...nums) => { console.log(num1, num2, nums); }; fn(1, 2); // 1 2 [] fn1(1, 2, 3, 4, 5, 6); // 1 2 [3,4,5,6]

image-20230130114626916

2. 展开运算符
const arr = ["css", "js", "ts", "vue"]; console.log(...arr); // css js ts vue

image-20230130134729410

3. 展开运算符和剩余参数运算符的区别
  • 剩余参数运算符:1,3,5 --> [1,3,5]
  • 展开运算符:[1,3,5] --> 1,3,5
const diff = (...args) => { console.log(args); // 剩余参数运算符:[1,3,5] console.log(...args); // 展开运算符:1,3,5 }; diff(1, 3, 5);

image-20230130134620508

二、 ...的用法举例

image-20230130142858435

1. 数组
(1)数组复制
const citys = ["南京", "北京", "上海", "成都", "杭州"]; const citysCopy = [...citys]; console.log(citysCopy); // ["南京", "北京", "上海", "成都", "杭州"]

image-20230130140244645

(2)数组去重
const colors = ["red", "orange", "yellow", "green", "orange"]; const onlyColors = [...new Set(colors)]; console.log(onlyColors); // ["red", "orange", "yellow", "green"]

image-20230130140501021

(3)数组合并
const animals = ["cat", "dog"]; const seasons = ["spring", "summer"]; const animalsAndSeasons = [...animals, ...seasons]; console.log(animalsAndSeasons); // ["cat", "dog", "spring", "summer"]

image-20230130140639577

(4)数组切片
const digitals = ["pc", "watch", "camera", "keyboard", "mouse"]; const [pc, ...otherDigitals] = digitals; console.log(otherDigitals); // ["watch", "camera", "keyboard", "mouse"]

image-20230130140750621

(5)数组作为参数进行传递
  • 数组个数等于形参个数:一一对应
  • 数组个数小于形参个数:缺少值为 undefined
  • 数组个数大于形参个数:多的参数值被忽略
  • 调用函数的时候使用运算符(...),会把原本聚拢在一起的数据拆分传递给各个参数
const phone1 = ["apple", "vivo", "oppo"]; const phone2 = ["apple", "vivo"]; const phone3 = ["apple", "vivo", "oppo", "华为"]; const mixer = (brand1, brand2, brand3) => { console.log(brand1, brand2, brand3); }; mixer(...phone1); // 等于:一一对应,apple vivo oppo mixer(...phone2); // 小于:缺少值为undefined,apple vivo undefined mixer(...phone3); // 多于:多的参数值被忽略,apple vivo oppo

image-20230130141120446

(6)将类数组转换为数组
const argsTransformArr = (...args) => console.log(args); argsTransformArr("pineapple"); // ["pineapple"] argsTransformArr(66, 88, 99); // [66, 88, 99]

image-20230130141516082

2. 对象
(1)复制对象
const student = { name: "Jack", school: { class: "Software Engineering Class 2" } }; const studentCopy = { ...student }; console.log(studentCopy); // {name: "Jack",school:{class: "Software Engineering Class 3"}}

image-20230130141746669

(2)合并对象——属性各不相同
  • 新对象包含了合并的对象的所有属性
const personName = { name: "nina" }; const personSex = { sex: "female" }; const personAge = { age: 18 }; const person = { ...personName, ...personSex, ...personAge }; console.log(person); // {name: "nina", sex: "female", age: 18}

image-20230130142210582

(3)合并对象——包含相同属性
  • 合并的对象中包含有同名的属性,则后面对象中的属性值覆盖前面的同名的属性值
const fruit1 = { name: "apple", color: "red" }; const fruit2 = { name: "strawberry", weight: "20g" }; const fruit = { ...fruit1, ...fruit2 }; console.log(fruit); // {name: "strawberry", color: "red", weight: "20g"}

image-20230130143009647

(4)内部属性为对象进行展开——内部对象不会展开
const fruit3 = { detail: { name: "apple", size: "big", weight: "300g" } }; console.log({ ...fruit3 });

image-20230130143607520

(5)非对象展开
  • 展开的是空对象,则仍然是空对象
  • 展开的不是对象,则会自动将其转为对象,但是新创建的对象由于并不包含任何属性,故为空对象
console.log({ ...{} }); // {} console.log({ ...1 }); // {} console.log({ ...undefined }); // {} console.log({ ...null }); // {} console.log({ ...true }); // {}

image-20230130144633177

3. 数组与对象合并使用
const tableData1 = { list: [ { name: "张三", address: "南京" }, { name: "李四", address: "北京" } ], pageSize: 10, pageNum: 1 }; const tableData2 = { list: [ { name: "王五", address: "深圳" }, { name: "赵六", address: "上海" } ], pageSize: 20, pageNum: 2 }; const allTableDate = { ...tableData1, list: [...tableData1.list, ...tableData2.list] }; console.log(allTableDate);

image-20230130160557857

4. 字符串
const name = "Song"; console.log(...name); // 直接展开,S o n g console.log([...name]); // 数组形式展开,["S", "o", "n", "g"] console.log({ ...name }); // 对象形式展开,{0: "S", 1: "o", 2: "n", 3: "g"}

image-20230130161553134

三、 注意点

image-20230130170230792

1. 数组复制
  • 通过运算符(...)拷贝数组值类型的属性被深度拷贝了(用的不同对象),而引用类型的属性只是做了浅拷贝(复制的为引用地址,引用对象并未复制,即用的是同一个对象)
// 值类型 const citys = ["南京", "北京", "上海", "成都", "杭州"]; const citysCopy = [...citys]; citys[0] = "深圳"; console.log(citysCopy); // ["南京", "北京", "上海", "成都", "杭州"]

image-20230130165514421

 

// 引用类型 let users = [ { name: "小红", sex: "female" }, { name: "小明", sex: "male" } ]; let usersCopy = [...users]; users[0].name = "小花"; console.info(usersCopy);

image-20230130165642719

2. 对象复制
  • 通过运算符(...)拷贝对象值类型的属性被深度拷贝了(用的不同对象),而引用类型的属性只是做了浅拷贝(复制的为引用地址,引用对象并未复制,即用的是同一个对象)
let user = { name: "张三", sex: "男", address: { city: "北京" } }; let clonedUser = { ...user }; user.name = "李四"; user.address.city = "四川"; console.log(user); console.log(clonedUser);

image-20230130164051909

如有错误或遗漏,欢迎批评指正🌝

附送250套精选项目源码

源码截图

源码获取:关注公众号「码农园区」,回复 【源码】,即可获取全套源码下载链接

文章来源:https://blog.csdn.net/lwzhang1101/article/details/135358007
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。