javascript展开运算符(spread operator)有什么用途?【教程】

12次阅读

javaScript展开运算符(…)是处理可迭代对象和类数组的核心工具,用于解构、拼接与透传值;它提供浅拷贝能力,但嵌套结构仍为引用,且仅支持可迭代值,否则抛TypeError。

javascript展开运算符(spread operator)有什么用途?【教程】

javascript 展开运算符(...)不是语法糖,而是处理“可迭代对象”和“类数组”的核心工具——它解决的是值的解构、拼接与透传问题,不是为了写得更短而存在。

复制数组或对象时为什么不能直接用 =

因为 = 只是赋引用,修改副本会污染原数据。展开运算符提供浅层拷贝能力:

  • [...arr] 创建新数组,不共享内存;{...obj} 创建新对象,只拷贝自身可枚举属性
  • 注意:嵌套对象/数组仍为引用,{...obj} 不会深拷贝 obj.nested
  • 函数参数中用 function f(...args) 收集剩余参数,此时 args 是真数组,可直接调用 .map() 等方法

... 在函数调用中替代 .apply()

以前要展开数组作为参数必须写 math.max.apply(NULL, arr),现在直接写 Math.max(...arr)

  • 支持任意可迭代对象:Math.min(...new Set([1,2,3])) 合法
  • 但一次只能展开一个: fn(...a, ...b, ...c) 可以,fn(...a, 42, ...b) 也合法
  • 错误用法:fn(...a, 42, ...b, ...c) 没问题;但 fn(...a, ...b, 42) 也没问题——顺序不关键,关键是不能在非可迭代位置用 ...

合并数组或对象时,...Object.assign() 有什么区别

行为几乎一致,但有细微差异:

立即学习Java免费学习笔记(深入)”;

  • {...a, ...b} 中,b 的同名属性会覆盖 a;这和 Object.assign(a, b) 行为相同
  • Object.assign() 会触发 setter,{...a, ...b} 不会(它只读取属性值)
  • [...a, ...b]a.concat(b) 更直观,且能混入原始值:[...a, 99, ...b]
  • 性能上:小数据无差别;大数据量时,for 循环Array.prototype.push.apply() 可能略快,但可读性代价高

哪些地方不能用 ...?常见报错怎么识别?

展开运算符只接受可迭代(iterable)值,否则抛 TypeError: X is not iterable

  • 数字、nullundefined、普通对象(没实现 [symbol.iterator])都不能直接展开
  • 错误示例:[...42] → 报错;{...null} → 报错;const obj = {}; [...obj] → 报错
  • 修复方式:先确保是数组、字符串、Set、Map、arguments、nodeList 等原生可迭代类型;否则手动转成数组,如 [...Object.keys(obj)]Array.from(obj)
  • 箭头函数里没有 arguments,所以 const f = () => console.log(...arguments) 会报错——这里 arguments 是未声明变量

真正容易被忽略的点是:展开运算符的“惰性”——它不会提前执行迭代器,也不会缓存中间结果;每次展开都是实时遍历。这意味着如果源在展开过程中被修改(比如异步改了数组长度),结果可能出人意料。

text=ZqhQzanResources