CodeWalk

Object.assign() 和展开运算符在对象合并上有何区别?

作者:Yahuda · 2026-05-30 12:55

请比较 Object.assign() 和对象展开运算符(...)在对象合并与浅拷贝时的异同。

回答

Yahuda

相同点

  • 都是浅拷贝,只复制自身可枚举属性(不包括原型链)
  • 同名属性后面的覆盖前面的
  • 不会复制 getter(会读取值后复制)
  • Symbol 属性也可以复制

不同点

特性Object.assign(target, ...sources){...obj1, ...obj2}
返回值修改并返回 target返回新对象
修改原对象✅ 会修改 target 对象❌ 不修改原对象
触发 setter✅ 会触发 target 上的 setter❌ 使用 [[DefineOwnProperty]],不触发 setter
只读属性若 target 有只读属性会抛 TypeError正常创建新属性
使用场景合并到已有对象创建新对象副本
性能稍快(不创建新对象)稍慢(创建新对象)

示例

const target = { a: 1 };
const source = { b: 2 };

const result1 = Object.assign(target, source);
console.log(result1 === target); // true(target 被修改)
console.log(target); // { a: 1, b: 2 }

const result2 = { ...source };
console.log(result2 === source); // false(新对象)

// 展开运算符不能合并到已有对象
// 等价写法:Object.assign({}, obj1, obj2) ≈ { ...obj1, ...obj2 }

建议:创建一个新对象用 ...,合并到已有对象用 Object.assign