【js篇】扩展运算符(...)的作用及使用场景详解

185 阅读3分钟

在 JavaScript 中,扩展运算符(Spread Operator) 是 ES6 引入的一个非常实用的语法特性,它可以将数组、对象、字符串等“展开”为多个元素或属性。它极大地简化了代码书写,提升了可读性和开发效率。


✅ 一句话总结

扩展运算符 ... 可以将一个可迭代对象(如数组、对象、字符串等)展开为多个值,常用于合并、复制、解构数组和对象,以及函数调用时传参等场景。


✅ 一、对象中的扩展运算符(...)

🔹 基本作用:

将一个对象的所有可枚举自有属性展开到另一个对象中。

const bar = { a: 1, b: 2 };
const baz = { ...bar }; // 等价于 Object.assign({}, bar)
console.log(baz); // { a: 1, b: 2 }

🔹 合并对象(后覆盖前)

const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 };
const merged = { ...obj1, ...obj2 };
console.log(merged); // { a: 1, b: 3, c: 4 }

📌 特点:

  • 属性按顺序展开,后面的会覆盖前面的;
  • 不包括继承来的属性;
  • 不复制 Symbol 类型的键;
  • 浅拷贝:如果对象中包含嵌套对象,它们仍然是引用;

🔹 Redux 中的应用示例

在 Redux 的 reducer 函数中要求不能直接修改 state,可以使用扩展运算符创建新对象:

function userReducer(state = { name: 'Tom', age: 20 }, action) {
  switch (action.type) {
    case 'UPDATE_AGE':
      return { ...state, age: action.payload };
    default:
      return state;
  }
}

✅ 二、数组中的扩展运算符(...)

🔹 基本作用:

将数组转换为逗号分隔的参数序列,每次只能展开一层。

console.log(...[1, 2, 3]); // 输出:1 2 3
console.log(...[1, [2, 3], 4]); // 输出:1 [2, 3] 4

🔹 使用场景

1️⃣ 将数组作为参数传给函数

function add(x, y) {
  return x + y;
}

const numbers = [1, 2];
console.log(add(...numbers)); // 3

2️⃣ 复制数组(浅拷贝)

const arr1 = [1, 2];
const arr2 = [...arr1]; // 浅拷贝

3️⃣ 合并数组

const arr1 = ['two', 'three'];
const arr2 = ['one', ...arr1, 'four', 'five'];
console.log(arr2); // ["one", "two", "three", "four", "five"]

4️⃣ 解构赋值 + 扩展运算符

const [first, ...rest] = [1, 2, 3, 4, 5];
console.log(first); // 1
console.log(rest);  // [2, 3, 4, 5]

⚠️ 注意:

扩展运算符只能出现在解构表达式的最后位置,否则会报错:

const [...rest, last] = [1, 2, 3]; // ❌ 报错

5️⃣ 字符串转为数组

console.log([...'hello']); // ['h', 'e', 'l', 'l', 'o']

6️⃣ 转换类数组对象为数组(如 arguments)

function foo() {
  const args = [...arguments];
  console.log(args);
}
foo(1, 2, 3); // [1, 2, 3]

替代 ES5 写法:

Array.prototype.slice.call(arguments);

7️⃣ 数组去重 + Math 方法结合使用

const numbers = [10, 5, 8, 12, 3];
console.log(Math.max(...numbers)); // 12
console.log([...new Set(numbers)]); // 去重后的数组

✅ 三、常见误区与注意事项

注意事项说明
只展开一层对于嵌套数组或对象,只会浅层展开
不复制 Symbol 键如果对象中有 Symbol 类型的 key,不会被复制
不能展开不可遍历对象nullundefined、数字等,会抛出错误
对象合并是后覆盖前注意合并顺序对结果的影响

✅ 四、一句话总结

扩展运算符 ... 是现代 JavaScript 开发中不可或缺的工具,适用于数组复制、合并、解构、函数传参、对象合并等多种场景。但要注意它是浅拷贝,对于嵌套结构需要配合深拷贝方法使用。


💡 进阶建议

  • 在 Vue / React 开发中,推荐使用扩展运算符更新状态对象,保持不可变性;
  • 结合 immer.js 实现更安全的状态更新;
  • 使用 TypeScript 可以更好地推导类型和防止误操作;
  • 使用 ESLint 规则避免在解构中滥用扩展运算符导致性能问题;