【面试题】如何使用ES6 ... 让代码优雅一点?

简介: 【面试题】如何使用ES6 ... 让代码优雅一点?

 前端面试题库 (面试必备)            推荐:★★★★★

地址:前端面试题库

表妹一键制作自己的五星红旗国庆头像,超好看

前言

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

一、 ...的两种含义

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]

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

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

二、 ...的用法举例

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

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

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

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

(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

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

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"}}

(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}

(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"}

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

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

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

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"}

三、 注意点

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

let user = {
  name: "张三",
  sex: "男",
  address: {
    city: "北京"
  }
};
let clonedUser = { ...user };
user.name = "李四";
user.address.city = "四川";
console.log(user);
console.log(clonedUser);

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

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

 

前端面试题库 (面试必备)            推荐:★★★★★

地址:前端面试题库

相关文章
|
5月前
|
存储 前端开发 JavaScript
【面试题】你是如何让js 代码变得简洁的?
【面试题】你是如何让js 代码变得简洁的?
|
14天前
|
前端开发 JavaScript
JavaScript 面试系列:如何理解 ES6 中 Generator ?常用使用场景有哪些?
JavaScript 面试系列:如何理解 ES6 中 Generator ?常用使用场景有哪些?
|
2月前
|
Java 编译器 C++
【Java基础面试一】、为什么Java代码可以实现一次编写、到处运行?
这篇文章解释了Java能够实现“一次编写,到处运行”的原因,主要归功于Java虚拟机(JVM),它能够在不同平台上将Java源代码编译成的字节码转换成对应平台的机器码,实现跨平台运行。
【Java基础面试一】、为什么Java代码可以实现一次编写、到处运行?
|
2月前
|
存储 缓存 Java
面试问Spring循环依赖?今天通过代码调试让你记住
该文章讨论了Spring框架中循环依赖的概念,并通过代码示例帮助读者理解这一概念。
面试问Spring循环依赖?今天通过代码调试让你记住
|
2月前
|
JavaScript 前端开发 程序员
JS小白请看!一招让你的面试成功率大大提高——规范代码
JS小白请看!一招让你的面试成功率大大提高——规范代码
|
3月前
|
JSON 前端开发 数据格式
|
4月前
|
存储 算法 Java
面试高频算法题汇总「图文解析 + 教学视频 + 范例代码」之 二分 + 哈希表 + 堆 + 优先队列 合集
面试高频算法题汇总「图文解析 + 教学视频 + 范例代码」之 二分 + 哈希表 + 堆 + 优先队列 合集
|
5月前
|
数据采集 数据挖掘 Python
最全妙不可言。写出优雅的 Python 代码的七条重要技巧,2024年最新被面试官怼了还有戏吗
最全妙不可言。写出优雅的 Python 代码的七条重要技巧,2024年最新被面试官怼了还有戏吗
|
5月前
|
缓存 监控 算法
Python性能优化面试:代码级、架构级与系统级优化
【4月更文挑战第19天】本文探讨了Python性能优化面试的重点,包括代码级、架构级和系统级优化。代码级优化涉及时间复杂度、空间复杂度分析,使用内置数据结构和性能分析工具。易错点包括过度优化和滥用全局变量。架构级优化关注异步编程、缓存策略和分布式系统,强调合理利用异步和缓存。系统级优化则涵盖操作系统原理、Python虚拟机优化和服务器调优,需注意监控系统资源和使用编译器加速。面试者应全面理解这些层面,以提高程序性能和面试竞争力。
58 1
Python性能优化面试:代码级、架构级与系统级优化
|
5月前
|
数据采集 XML 程序员
最新用Python做垃圾分类_python垃圾分类代码用key和format,5年经验Python程序员面试27天
最新用Python做垃圾分类_python垃圾分类代码用key和format,5年经验Python程序员面试27天
最新用Python做垃圾分类_python垃圾分类代码用key和format,5年经验Python程序员面试27天
下一篇
无影云桌面