javascript展开运算符是什么_它有哪些常见用途?

展开语法...用于数组、对象、函数调用等场景,实现浅拷贝、合并、解构等功能,但不可单独使用,且对null/undefined会报错。

... 是 JavaScript 中用于“展开”可迭代对象(如数组、字符串、Map、Set)或对象属性的语法糖,不是运算符,也不能单独存在——它必须出现在数组字面量 [...arr]、对象字面量 {...obj} 或函数调用 func(...arr) 中。


合并数组时怎么避免嵌套?

常见错误是写成 [arr1, arr2],结果得到二维数组 [[1,2], [3,4]]。正确做法是加 ... 展开:

const arr1 = [1, 2];
const arr2 = [3, 4];
const merged = [...arr1, ...arr2]; // → [1, 2, 3, 4]
  • 支持插入字面量:[...arr1, 99, ...arr2]
  • 不修改原数组,返回新数组
  • 若需去重合并,可结合 Set[...new Set([...arr1, ...arr2])]

对象合并时同名属性谁生效?

对象展开按顺序覆盖:后写的属性会覆盖前面同名的值。

const defaults = { theme: 'light', lang: 'en' };
const userConfig = { theme: 'dark' };
const config = { ...defaults, ...userConfig }; // → { theme: 'dark', lang: 'en' }
  • 适合配置项覆盖场景(如默认配置 + 用户覆盖)
  • 仅浅合并:嵌套对象不会递归合并,defaults.nesteduserConfig.nested 仍是独立引用
  • 不能展开 nullundefined,否则报错;可用空值合并:{ ...(obj ?? {}) }

传参给函数时为什么不用 apply 了?

过去要写 Math.max.apply(null, arr),现在直接 Math.max(...arr) 更直观安全。

const numbers = [7, 2, 9];
console.log(Math.max(...numbers)); // → 9
console.log(sum(...numbers));       // → 18(假设 sum(a,b,c) => a+b+c)
  • 替代 func.apply(this, args) 的标准写法
  • 构造函数也适用:new Date(...[2025, 0, 1])
  • 注意:超大数组(>10万元素)可能触发栈溢出,此时应改用循环或 Math.max.apply(虽已过时但更耐扛)

复制和解构时要注意什么?

[...arr]{...obj} 都是浅拷贝——只复制第一层,嵌套结构仍共享引用。

const original = { a: 1, b: { c: 2 } };
const copy = { ...original };
copy.b.c = 99;
console.log(original.b.c); // → 99(被意外改了!)
  • 字符串也能展开:[...'hi'] → ['h', 'i'],常用于字符遍历或去重
  • 解构中配合剩余参数:const [first, second, ...rest] = [1,2,3,4,5];
  • 不能单独写 ...arr,会语法错误;必须在 []{}()

真正容易被忽略的是:它对 nullundefined、普通对象(非可迭代)直接展开会报错,而很多人只在开发环境试过“有值”的情况,上线后遇到空数据就崩。用之前先判空,比事后 debug 快得多。