用大白话搞懂 Object.assign()

86 阅读4分钟

一、Object.assign() 到底是啥?

Object.assign() 可以把多个对象的属性“合并”到第一个参数指定的目标对象里,并返回这个目标对象。

用人话说就是:把后面对象里的属性,一个个“拷贝”到第一个对象上,类似于“把东西塞进一个目标对象”。

二、基本语法

Object.assign(目标对象, 源对象1, 源对象2, ...)

要点:

  • 第一个参数是目标对象,后面的参数都是源对象
  • 会把源对象上的可枚举自有属性复制到目标对象
  • 返回值就是修改后的目标对象

ps.有不理解枚举是什么的同学可点击此处,一文带你轻松了解枚举。

三、基础示例

示例 1:合并两个对象

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

Object.assign(target, source);
console.log(target);  // { a: 1, b: 2, c: 3 }

说明:sourcebc 被复制到 targettarget 被修改并返回。

示例 2:合并多个对象

const obj1 = { a: 1 };
const obj2 = { b: 2 };
const obj3 = { c: 3 };

const result = Object.assign(obj1, obj2, obj3);
console.log(result);  // { a: 1, b: 2, c: 3 }
console.log(obj1);    // { a: 1, b: 2, c: 3 } —— obj1 被修改了

说明:从第二个参数开始的对象会依次合并到 obj1obj1 就是目标对象,会被直接改动。

示例 3:相同属性会被覆盖

const target = { a: 1, b: 2 };
const source = { b: 99, c: 3 };  // b 冲突了

Object.assign(target, source);
console.log(target);  // { a: 1, b: 99, c: 3 }

说明:后面的对象会覆盖前面的同名属性,这里是 sourceb: 99 覆盖了原来的 b: 2

四、常见使用场景

场景 1:创建对象副本(浅拷贝)

const original = { name: '小明', age: 18 };
const copy = Object.assign({}, original);

copy.age = 20;
console.log(original.age);  // 18 —— 原对象没变
console.log(copy.age);      // 20

要点:目标对象用空对象 {},这样不会修改原对象,只得到一份浅拷贝。

场景 2:给对象添加默认值

function createUser(options) {
  return Object.assign({}, {
    name: '匿名用户',
    age: 0,
    role: 'guest'
  }, options);  // 用户传入的 options 会覆盖默认值
}

console.log(createUser({ name: '小红' }));
// { name: '小红', age: 0, role: 'guest' }

说明:先用默认对象,再合并用户传入的 options,实现默认值逻辑。

场景 3:复制并修改对象属性

const user = { name: '张三', age: 25 };
const updatedUser = Object.assign({}, user, { age: 26 });

console.log(user);         // { name: '张三', age: 25 }
console.log(updatedUser);  // { name: '张三', age: 26 }

说明:先拷贝 user 到空对象,再覆盖 age,得到新对象,原对象不变。

五、注意事项

1. 浅拷贝,不是深拷贝

const obj1 = { a: 1, nested: { b: 2 } };
const obj2 = Object.assign({}, obj1);

obj2.nested.b = 999;
console.log(obj1.nested.b);  // 999 —— 原对象里的嵌套对象也被改了!

嵌套对象还是同一个引用,修改 obj2.nested 会影响到 obj1.nested。需要深拷贝时要用递归、结构化克隆或 lodash.cloneDeep 等。

补充 - 深浅拷贝定义:

  • 浅拷贝:仅复制对象的表层结构,对嵌套的引用类型仅复制内存引用,新旧对象共享嵌套数据。
  • 深拷贝:完整复制对象的所有层级结构(含所有嵌套引用类型),新旧对象完全独立、无数据共享。

2. 只复制可枚举自有属性

const obj = Object.create({ inherit: '继承属性' });
obj.own = '自有属性';

const result = Object.assign({}, obj);
console.log(result);  // { own: '自有属性' } —— 继承属性不会被复制

说明:只复制源对象自身的可枚举属性,原型链上的属性不会被复制。

3. 会修改目标对象

const target = { a: 1 };
Object.assign(target, { b: 2 });
console.log(target);  // { a: 1, b: 2 } —— target 被改变了

第一个参数会被直接修改,如果不希望影响原对象,可以把第一个参数写成 {}

4. 源参数不是对象时的处理

Object.assign({}, undefined, null, 123, 'abc');
// 忽略 undefined、null、数字,字符串会按字符拆分
// 结果: { 0: 'a', 1: 'b', 2: 'c' }
  • undefinednull 会被跳过
  • 基本类型会先包装成对象,字符串会被当成类数组对象处理,一般不推荐这样用

六、和展开运算符的区别

const obj1 = { a: 1 };
const obj2 = { b: 2 };

// 方式 1:Object.assign
const result1 = Object.assign({}, obj1, obj2);

// 方式 2:展开运算符
const result2 = { ...obj1, ...obj2 };

console.log(result1);  // { a: 1, b: 2 }
console.log(result2);  // { a: 1, b: 2 }

两者都能合并对象,通常用展开运算符 { ...obj1, ...obj2 } 更直观;需要修改已有目标对象、或者处理非对象参数时,再用 Object.assign 更合适。

七、总结

要点说明
作用把多个源对象的属性合并到目标对象
第一个参数目标对象,会被修改
返回值修改后的目标对象
拷贝方式浅拷贝
常见用法对象浅拷贝、添加默认值、合并多个对象

一句话:Object.assign(目标, 源1, 源2, ...) 就是“把后面的对象属性依次塞进第一个对象里”。

以上就是本次的学习分享,欢迎大家在评论区讨论指正,与大家共勉。

我是 Eugene,你的电子学友。

如果文章对你有帮助,别忘了点赞、收藏、加关注,你的认可是我持续输出的最大动力~