回归基本功!前端的解构赋值、扩展运算符、剩余参数

一、解构赋值(Destructuring Assignment)

作用:按模式从数组或对象中提取值,并赋给变量。

1. 数组解构

按位置匹配:

js 复制代码
const arr = [1, 2, 3];
const [a, b, c] = arr;
console.log(a, b, c); // 1 2 3

// 跳过元素
const [, , third] = arr;
console.log(third); // 3

// 默认值
const [x, y = 10] = [5];
console.log(x, y); // 5 10

// 嵌套解构
const [i, [j, k]] = [1, [2, 3]];
console.log(i, j, k); // 1 2 3

2. 对象解构

按属性名匹配,顺序无关:

js 复制代码
const user = { name: 'Alice', age: 25 };
const { name, age } = user;
console.log(name, age); // 'Alice' 25

// 重命名
const { name: userName, age: userAge } = user;
console.log(userName); // 'Alice'

// 默认值
const { role = 'user' } = user;
console.log(role); // 'user'

// 嵌套解构
const person = { 
  name: 'Bob', 
  address: { city: 'Beijing' } 
};
const { address: { city } } = person;
console.log(city); // 'Beijing'

3. 函数参数解构

直接提取形参:

js 复制代码
function greet({ name, age }) {
  console.log(`${name} is ${age}`);
}
greet({ name: 'Tom', age: 30 }); // Tom is 30

// 配合默认值
function draw({ x = 0, y = 0 } = {}) {
  console.log(x, y);
}
draw(); // 0 0

4. 用途场景

  • 交换变量[a, b] = [b, a];
  • 提取 JSON 数据import 具名导出等。
  • 解析函数返回值
js 复制代码
function getInfo() {
  return { status: 200, data: [1,2] };
}
const { status, data } = getInfo();

二、扩展运算符(Spread Operator)

语法...可迭代对象 (数组、字符串等)或对象前使用,将其展开为单独元素。

1. 数组扩展

js 复制代码
// 复制数组(浅拷贝)
const arr1 = [1, 2, 3];
const arr2 = [...arr1];

// 合并数组
const arr3 = [...arr1, 4, 5];
console.log(arr3); // [1,2,3,4,5]

// 将类数组/可迭代对象转为真数组
const nodeList = document.querySelectorAll('div');
const divArray = [...nodeList];

// 与解构结合(剩余属性在解构中也是 ...)
const [first, ...rest] = [10, 20, 30];
console.log(rest); // [20, 30]

2. 对象扩展

js 复制代码
// 浅拷贝对象
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1 };

// 合并对象,同名属性后者覆盖前者
const merged = { ...obj1, c: 3, a: 99 };
console.log(merged); // { a: 99, b: 2, c: 3 }

// 用于为对象添加属性(不可变更新)
const newUser = { ...oldUser, age: 26 };

3. 函数调用扩展

将数组展开为独立参数:

js 复制代码
const nums = [5, 2, 9];
Math.max(...nums); // 相当于 Math.max(5, 2, 9)

// 与普通参数混用
function sum(a, b, c) { return a + b + c; }
sum(...[1, 2, 3]); // 6

4. 注意事项

  • 扩展运算符执行的是浅拷贝,嵌套对象仍共享引用。
  • 对于对象扩展,是 ES2018 引入,与数组扩展的 ... 语法相同但语义不同(对象扩展不是迭代行为,而是枚举自身可枚举属性)。

三、剩余参数(Rest Parameters)

语法...函数声明或解构赋值中,将剩余元素收集为一个数组。

1. 函数剩余参数

将不定数量的参数收集为数组,替代 arguments

js 复制代码
function logAll(...args) {
  console.log(args); // 真数组,可使用 map、filter 等
}
logAll(1, 'a', true); // [1, 'a', true]

// 收集剩余参数
function multiply(factor, ...nums) {
  return nums.map(n => n * factor);
}
multiply(2, 1, 2, 3); // [2, 4, 6]

注意

  • 剩余参数必须是函数的最后一个参数
  • 箭头函数没有 arguments,必须用剩余参数。

2. 解构中的剩余模式

收集数组/对象中未被提取的部分:

js 复制代码
// 数组剩余
const [head, ...tail] = [1, 2, 3, 4];
console.log(tail); // [2, 3, 4]

// 对象剩余
const { a, b, ...rest } = { a: 1, b: 2, c: 3, d: 4 };
console.log(rest); // { c: 3, d: 4 }

对象剩余属性也是浅拷贝,并只收集自身的可枚举属性。


四、三者对比与关键区别

特性 解构赋值 扩展运算符 剩余参数
作用 拆分数据为变量 展开数据为元素 收集元素为数组
语法位置 赋值表达式的左边 字面量或函数调用的右边 函数参数或解构赋值左边
典型语法 const { x } = obj [...arr], {...obj} function(...args)
运作方向 分解 展开 聚集
返回值 变量 新的数组/对象 数组

五、综合示例:解构 + 扩展 + 剩余参数

js 复制代码
const obj = { x: 1, y: 2, z: 3, w: 4 };
const { x, ...others } = obj; // 解构 + 剩余
console.log(others); // { y: 2, z: 3, w: 4 }

const newObj = { ...others, x: 10 }; // 扩展,覆盖 x
console.log(newObj); // { y: 2, z: 3, w: 4, x: 10 }

function process(first, ...rest) {
  const combined = [first, ...rest.map(v => v * 2)]; // 扩展
  return combined;
}
console.log(process(5, 1, 2, 3)); // [5, 2, 4, 6]
相关推荐
bonechips1 小时前
JS 数组指南:从内存原理到二维矩阵
前端·javascript
亿元程序员2 小时前
美术妹子让我给模型加个描边,我差点把Cocos卸了
前端
Lee川2 小时前
Memory 模块深度解析(面试向)
人工智能·面试
IT_陈寒2 小时前
React的useEffect依赖数组把我坑惨了,真相其实很简单
前端·人工智能·后端
徐小夕2 小时前
JitWord 3.0 正式发布,高精度Word异构解析+复杂组件兼容,打造web端协同Word编辑器
前端·vue.js·算法
恋猫de小郭2 小时前
KMP / CMP 鸿蒙版本 Beta 发布,他有什么特别之处?
android·前端·flutter
乘风gg3 小时前
OpenClaw 爆火,但”飞书"赢麻了!!!
前端·ai编程·claude
Oneslide3 小时前
React 纯前端技术栈报告(2026年)
前端