一、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 }
说明:source 的 b、c 被复制到 target,target 被修改并返回。
示例 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 被修改了
说明:从第二个参数开始的对象会依次合并到 obj1,obj1 就是目标对象,会被直接改动。
示例 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 }
说明:后面的对象会覆盖前面的同名属性,这里是 source 的 b: 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' }
undefined、null会被跳过- 基本类型会先包装成对象,字符串会被当成类数组对象处理,一般不推荐这样用
六、和展开运算符的区别
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,你的电子学友。
如果文章对你有帮助,别忘了点赞、收藏、加关注,你的认可是我持续输出的最大动力~