展开运算符可对异步返回的数组或对象实现按需合并与浅拷贝,确保当前层级独立、避免原始数据被修改;适用于隔离响应数据、合并多接口结果、响应式更新等场景,但仅作用于第一层。

直接用展开运算符对异步返回的数组或对象做一层解构,就能完成按需合并与浅拷贝——它不等待后续嵌套结构变化,只确保当前层级独立,避免原始结果被意外覆盖。
拿到异步结果后立即浅拷贝
异步请求(如 fetch、axios 或小程序 wx.request)返回的数据常被多次复用。若直接赋值 data = res.data,后续对 data 的修改会反向影响原始响应缓存或其它引用。用展开语法可一步隔离:
- 数组:const safeList = [...res.data];
- 对象:const safeItem = { ...res.data };
- 混合结构(如带分页字段):const { list, total, ...rest } = res.data; const merged = { total, list: [...list], ...rest };
合并多个异步结果时保持各自独立
当需要把几个接口返回的数组拼成一个列表(比如“推荐商品”+“历史浏览”),展开运算符天然支持动态拼接,且每段都已浅拷贝:
- const allItems = [...recommendRes.data, ...historyRes.data];
- 如果某结果是 null/undefined,先兜底:[...(recommendRes?.data || []), ...(historyRes?.data || [])];
- 避免错误写法:[recommendRes.data, historyRes.data] —— 这会生成二维数组,不是合并。
处理嵌套结构时明确“哪层需要隔离”
展开运算符只拷贝第一层。若 res.data 是 { user: { name, profile }, tags: [...] },而你只打算改 tags,但要保留 user 引用不变,就该:
- 仅深拷贝 tags:{ ...res.data, tags: [...res.data.tags] };
- 若 user.profile 也要独立修改,就不能只靠展开——得用 structuredClone() 或手动递归处理;
- 常见误判:以为 { ...res.data } 能让所有子对象都变独立,其实 user.profile.city 改了,原 res.data.user.profile.city 也会变。
在 setData / useState 等响应式更新中安全使用
前端框架(React、Vue、小程序)要求状态更新必须是新引用。展开运算符正好满足这个前提,同时避免深层污染:
- React:setItems(prev => [...prev, ...newItems]);
- 小程序:this.setData({ list: [...this.data.list, ...res.data] });
- 注意不要写成 this.setData({ list: this.data.list.concat(res.data) })——concat 也行,但展开更直观、更易读出“新建数组”的意图。

















