ES6中{...arr}合并对象数组报错,该语法是否支持?
问题解答
首先明确:你用{ ...arr }的语法错误(或不符合预期),本质是混淆了对象字面量扩展运算符和函数调用中的数组展开语法的用法。
1. 为什么{ ...arr }不行?
对象字面量里的...运算符,作用是展开单个对象的可枚举属性到新对象中。你这里的arr是数组,虽然数组属于对象范畴,但直接写{ ...arr }时,JS会把数组当作普通对象处理——展开它的索引属性(比如0、1、2这些键),得到的结果会是:
{ 0: { a: 42, b: 69 }, 1: { b: "hi", c: "bye" }, 2: { c: NaN } }
而你遇到的Firefox语法错误,大概率是因为使用的浏览器版本较早,对“在对象字面量中展开数组”的支持不完善(早期ES2018对象扩展规范落地时,部分浏览器存在兼容延迟),但即便支持,结果也完全不是你想要的对象合并效果。
2. 为什么Object.assign({}, ...arr)能生效?
Object.assign(target, ...sources)的第二个及以后参数是待合并的源对象。这里的...arr是函数调用中的数组展开语法——它会把数组arr的每个元素(也就是那三个对象)依次作为独立参数传递给Object.assign,相当于执行:
Object.assign({}, { a: 42, b: 69 }, { b: "hi", c: "bye" }, { c: NaN })
这正好匹配你“靠后的对象覆盖靠前对象”的需求,所以能得到预期结果。
3. 用扩展运算符实现需求的正确写法
如果想用对象扩展运算符达到同样效果,需要把数组里的每个对象逐个展开到新对象中:
- 若数组长度固定,可直接写:
const merged = { ...arr[0], ...arr[1], ...arr[2] };
- 若数组长度不确定,更灵活的写法是用数组
reduce方法:
const merged = arr.reduce((acc, curr) => ({ ...acc, ...curr }), {});
这个逻辑和Object.assign一致:从空对象开始,依次把每个数组元素的属性合并到累加器中,靠后的对象自动覆盖靠前的同名属性。
内容的提问来源于stack exchange,提问作者Ryan Pierce Williams
相关产品推荐
相关产品推荐

