CodeAshen's blog CodeAshen's blog
首页
  • Spring Framework

    • 《剖析Spring5核心原理》
    • 《Spring源码轻松学》
  • Spring Boot

    • Spring Boot 2.0深度实践
  • Spring Cloud

    • Spring Cloud
    • Spring Cloud Alibaba
  • RabbitMQ
  • RocketMQ
  • Kafka
  • MySQL8.0详解
  • Redis从入门到高可用
  • Elastic Stack
  • 操作系统
  • 计算机网络
  • 数据结构与算法
  • 云原生
  • Devops
  • 前端
  • 实用工具
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
  • Reference
GitHub (opens new window)

CodeAshen

后端界的小学生
首页
  • Spring Framework

    • 《剖析Spring5核心原理》
    • 《Spring源码轻松学》
  • Spring Boot

    • Spring Boot 2.0深度实践
  • Spring Cloud

    • Spring Cloud
    • Spring Cloud Alibaba
  • RabbitMQ
  • RocketMQ
  • Kafka
  • MySQL8.0详解
  • Redis从入门到高可用
  • Elastic Stack
  • 操作系统
  • 计算机网络
  • 数据结构与算法
  • 云原生
  • Devops
  • 前端
  • 实用工具
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
  • Reference
GitHub (opens new window)
  • CSS3浮动定位与背景样式

  • CSS动画

  • JS基础语法与表达式

  • 流程控制语句与数组

  • JS函数与DOM

  • 面向对象

  • 正则表达式

  • ES6基础入门

  • ES6语法扩展

    • 01-剩余参数与展开运算符
      • 函数参数中的剩余参数
      • 解构赋值中的剩余参数
      • 数组的展开运算符
        • 什么是展开运算符
        • 数组展开运算符的应用
      • 对象的展开运算符
        • 展开对象
        • 对象展开运算符的注意事项
        • 对象展开运算符的应用
    • 02-Set和Map
    • 03-迭代器与循环
    • 04-ES6新增方法
  • Promise与Class

  • Module与Babel

  • 前端
  • ES6语法扩展
CodeAshen
2023-02-10
目录

01-剩余参数与展开运算符

# 剩余参数

# 函数参数中的剩余参数

剩余参数类似于 Java 中的可变参数。JavaScript 中的剩余参数永远是个数组,即使没有值,也是空数组

const add = (x, y, ...args) => {
  console.log(x, y, args);
};

add();              // undefined undefined []
add(1);             // 1 undefined []
add(1, 2);          // 1 2 []
add(1, 2, 3, 4, 5); // 1 2 [3, 4, 5]
1
2
3
4
5
6
7
8

箭头函数的参数部分即使只有一个剩余参数,也不能省略圆括号。

const add = (...args) => {};
1

箭头函数可以使用剩余参数替代普通函数中的 arguments 获取实际参数。

const add1 = function () {
  console.log(arguments);
};

const add2 = (...args) => {
  console.log(args);
};
1
2
3
4
5
6
7

剩余参数只能是最后一个参数,之后不能再有其他参数,否则会报错。

# 解构赋值中的剩余参数

剩余参数不一定非要作为函数参数使用,还可以用于解构赋值。

数组剩余参数的解构赋值:

const [num, ...args] = [1, 2, 3, 4];
console.log(num, args);  // 1 [2, 3, 4]

const func = ([num, ...args]) => {};
func([1, 2, 3]);
1
2
3
4
5

对象剩余参数的解构:

const { x, y, ...z } = { a: 3, x: 1, y: 2, b: 4 };
console.log(x, y, z);  // 1 2 { a: 3, b: 4 }

const func = ({ x, y, ...z }) => {};
func({ a: 3, x: 1, y: 2, b: 4 });
1
2
3
4
5

# 展开运算符

# 数组的展开运算符

# 什么是展开运算符

什么是展开运算符,通过一个例子介绍。我们要获取一个数组中最小的元素,怎么实现呢。可以想到 Math.min(),但是这个函数的参数不是数组,这时候就可以用到展开运算符。

let res = Math.min(...[3, 1, 2]);

// 相当于:
let res2 = Math.min(3, 1, 2)
1
2
3
4

可以看到展开运算符和剩余参数的语法相同,如何区分呢?

  • 展开运算符是将数组展开为元素列表,[3,1,2] -> 3,1,2
  • 剩余参数是将元素列表转换为数组,3,1,2 -> [3,1,2]
// 展开运算符
let arr = [...[1, 2, 3], 4];   // [1, 2, 3, 4]

// 剩余参数
let [a, ...b] = [1, 2, 3, 4]
console.log(a)   // 1
console.log(b)   // [2, 3, 4]
1
2
3
4
5
6
7

# 数组展开运算符的应用

(1)复制数组

const a = [1, 2];

// 使用展开运算符创建出 a 数组的副本
const b = [...a];
1
2
3
4

(2)合并数组

const a = [1, 2];
const b = [3];
const c = [4, 5];

// 合并数组 a、b、c,并且追加了一个元素 1
const all = [...a, ...b, ...c, 1]
1
2
3
4
5
6

(3)字符串转为数组

// 字符串可以按照数组的形式展开
console.log(...'alex');  // a l e x

// 字符串转数组
const arr = [...'alex'];  // ['a', 'l', 'e', 'x']
// 相当于
const arr2 = 'alex'.split('');
1
2
3
4
5
6
7

(4)常见的类数组转化为数组

// arguments
function func() {
  // console.log(arguments.push);
  console.log([...arguments]);
}
func(1, 2);

// NodeList
console.log(document.querySelectorAll('p'));
console.log([...document.querySelectorAll('p')].push);
1
2
3
4
5
6
7
8
9
10

# 对象的展开运算符

# 展开对象

展开对象要放在 {} 中,得到一个新对象。

const apple = {
  color: '红色',
  shape: '球形',
  taste: '甜'
};

const apple2 = { ...apple };
1
2
3
4
5
6
7

可以用来合并对象,如果由相同属性,后面的覆盖前面的。

const apple = {
  color: '红色',
  shape: '球形',
  taste: '甜'
};
const pen = {
  color: '黑色',
  shape: '圆柱形',
  use: '写字'
};

const applePen = { ...apple, ...pen };
1
2
3
4
5
6
7
8
9
10
11
12

# 对象展开运算符的注意事项

如果展开一个空对象,则没有任何效果

console.log({ ...{} });        // {}
console.log({ ...{}, a: 1 });  // {a: 1}
1
2

如果展开的不是对象,则会自动将其转为对象,再将其属性罗列出来。

// 下面打印出的都是空对象 {}
console.log({ ...1 });
console.log(new Object(1));
console.log({ ...undefined });
console.log({ ...null });
console.log({ ...true });
1
2
3
4
5
6

如果展开运算符后面是字符串,它会自动转成一个类似数组的对象,因此返回的不是空对象。

console.log({ ...'alex' });  // {0: 'a', 1: 'l', 2: 'e', 3: 'x'}
console.log([...'alex']);    // ['a', 'l', 'e', 'x']
console.log(...'alex');      // a l e x
1
2
3

对象中对象属性不会递归展开。

const apple = {
  color: 'red',
  feature: {
    taste: '甜'
  }
};

// 不会展开 feature 中的属性
console.log({ ...apple });
1
2
3
4
5
6
7
8
9

# 对象展开运算符的应用

可以用来复制对象和合并对象,前面已经说过了。

还可以用来属性覆盖,其实就是用合并对象的方式覆盖属性。比如由默认参数和用户自定义参数,没传自定义参数就取默认值,否则用用户自定义参数。

const logUser = userParam => {
  // 默认参数
  const defaultParam = {
    username: 'ZhangSan',
    age: 0,
    sex: 'male'
  };

  // 用户参数覆盖默认参数
  const finalParam = { ...defaultParam, ...userParam };

  console.log(finalParam.username);
};

logUser();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
编辑 (opens new window)
上次更新: 2023/06/04, 12:34:19
04-对象字面量的增强与函数参数的默认值
02-Set和Map

← 04-对象字面量的增强与函数参数的默认值 02-Set和Map→

最近更新
01
第01章-RabbitMQ导学
02-10
02
第02章-入门RabbitMQ核心概念
02-10
03
第03章-RabbitMQ高级特性
02-10
更多文章>
Theme by Vdoing | Copyright © 2020-2023 CodeAshen | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式