Spread运算符在Object.assign()中无法正常工作的问题排查
问题分析与解决方案
嘿,我来帮你拆解下遇到的这两个问题~
一、新对象为空的可能原因
你遇到新对象为空的情况,大概率是对象扩展运算符的语法写错了,或者你的运行环境不支持对象扩展语法,导致代码没正确执行。
比如如果错误地用数组的扩展语法来复制对象:
const obj = { name: 'test', age: 20 }; const test1 = [...obj]; // 这会直接报错,若环境兼容度差甚至可能得到空数组或无有效输出
正确的对象扩展语法必须用大括号包裹,这样才能把原对象的可枚举属性复制到新对象里:
const obj = { name: 'test', age: 20 }; const test1 = { ...obj }; // 这样test1就会和obj内容完全一致,且是独立的新对象
如果你的代码确实是{...obj}但还是得到空对象,那得检查原对象obj本身是不是就为空,或者有没有在复制前被意外清空了哦。
二、本地环境报Unexpected token的原因
JSBin默认启用了对ES2018+新语法的支持,但你的本地环境(比如旧版Node.js、没配置Babel的前端项目、老浏览器)不支持对象扩展运算符——因为对象扩展是ES2018(也就是ES9)才正式纳入标准的,在此之前的环境根本识别不了{...obj}这种写法,所以会在第一个.处抛出语法错误。
解决环境问题的几个办法:
- 升级Node.js版本:如果是Node环境,升级到v8.3.0及以上(v8.x开始部分支持,v10+完全支持ES2018语法);
- 配置Babel转译:如果是前端项目,通过Babel把ES2018语法转成兼容旧环境的ES5代码,需要安装
@babel/plugin-proposal-object-rest-spread插件并在配置文件中启用; - 切换浏览器的现代模式:如果是浏览器环境,确保用Chrome 60+、Firefox 55+这类支持ES2018的现代浏览器,或者给script标签加
type="module"属性,让浏览器启用ES模块模式,默认支持更多新语法:
<script type="module"> const obj = { a: 1 }; const test1 = { ...obj }; </script>
三、不用Object.assign()的替代方法
除了对象扩展运算符,这些方式也能复制对象(避免指针引用):
- 手动遍历属性:适合兼容极低版本的环境,手动复制每个可枚举属性:
const obj = { name: 'test', age: 20 }; const test1 = {}; for (const key in obj) { if (obj.hasOwnProperty(key)) { test1[key] = obj[key]; } }
- 对象解构重组:本质和扩展运算符原理类似,适合属性少或者需要同时添加新属性的场景:
const obj = { name: 'test', age: 20 }; // 完整复制 const test1 = { ...obj }; // 只复制部分属性+新增属性 const test2 = { name: obj.name, age: obj.age, gender: 'male' };
- JSON序列化反序列化:注意这种方法只能复制可序列化的属性(函数、Symbol、undefined这类会丢失),适合纯数据对象的复制:
const obj = { name: 'test', age: 20 }; const test1 = JSON.parse(JSON.stringify(obj));
内容的提问来源于stack exchange,提问作者NotoriousWebmaster




