前言
需要将一个或多个对象的属性合并到目标对象中时,Object.assign()
是一个非常有用的工具
以下是对 Object.assign()
的详细分析、概念解释和演示示例
1. 基本知识
Object.assign()
是 JavaScript 中一个用于复制一个或多个源对象自身可枚举的属性到目标对象的方法
它的语法如下:
Object.assign(target, ...sources)
具体的参数说明:
target
:目标对象,其他对象的属性将被复制到该对象sources
:一个或多个源对象,它们的属性将被复制到目标对象中。可以传递多个源对象
2. 基本操作
- 合并对象属性:
source 对象的属性被复制到了 target 对象中
如果目标对象 (target) 已经有相同的属性,则它将被源对象 (source) 中的属性覆盖
const target = { a: 1, b: 2 };
const source = { b: 3, c: 4 };
const result = Object.assign(target, source);
console.log(result); // { a: 1, b: 3, c: 4 }
console.log(target); // { a: 1, b: 3, c: 4 }
- 克隆对象:
使用Object.assign()
将 obj 对象的属性复制到一个空对象中,从而实现了对 obj 的浅拷贝,即生成了一个 obj 的副本
const obj = { a: 1, b: 2, c: 3 };
const clone = Object.assign({}, obj);
console.log(clone); // { a: 1, b: 2, c: 3 }
克隆对象所使用的的是浅拷贝,所谓的浅拷贝,深拷贝推荐阅读:浅拷贝和深拷贝的深度理解
(ps:这是以前配合Java写的相关文章,如果是前端可不用点开!!)
总的来说 Object.assign()
执行的是浅拷贝,即它只会复制对象的自身可枚举属性,不会复制对象的原型链上的属性
如果某个源对象的属性值是一个指向对象的引用,那么该引用指向的对象不会被复制,而是共享到目标对象中
3. 深入理解
结合代码讲解 浅拷贝和深拷贝中的差异
3.1 浅拷贝
浅拷贝只复制对象的第一层属性,而不会复制嵌套对象的属性
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = Object.assign({}, obj1);
obj2.b.c = 3;
console.log(obj1); // { a: 1, b: { c: 3 } }
console.log(obj2); // { a: 1, b: { c: 3 } }
在这个示例中,虽然只修改了 obj2 的 b 属性的 c 值,但是 obj1 的 b 属性也受到了影响,这是因为它们共享了相同的引用
3.2 深拷贝
深拷贝会复制对象的所有属性,包括嵌套对象的属性。
一共有两种方式进行深拷贝:
- 方式一:使用递归实现深拷贝
使用了递归来实现深拷贝
deepClone 函数会递归地复制所有嵌套对象的属性,因此 obj1 和 obj2 完全独立,修改一个不会影响另一个
function deepClone(obj) {
if (obj === null || typeof obj !== 'object') {
return obj;
}
const clone = Object.assign({}, obj);
Object.keys(clone).forEach(key => {
clone[key] = deepClone(clone[key]);
});
return clone;
}
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = deepClone(obj1);
obj2.b.c = 3;
console.log(obj1); // { a: 1, b: { c: 2 } }
console.log(obj2); // { a: 1, b: { c: 3 } }
- 方式二:使用 JSON 实现深拷贝
使用JSON.stringify()
将对象转换为 JSON 字符串,再使用JSON.parse()
将 JSON 字符串转换为对象,可以实现一种简单的深拷贝
这种方法有一些限制,例如无法复制函数、正则表达式等特殊对象
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = JSON.parse(JSON.stringify(obj1));
obj2.b.c = 3;
console.log(obj1); // { a: 1, b: { c: 2 } }
console.log(obj2); // { a: 1, b: { c: 3 } }
总的来说,Object.assign()
只能实现浅拷贝,对于嵌套对象的属性,只复制了引用而不是对象本身。深拷贝则会递归地复制对象的所有属性,包括嵌套对象的属性,从而生成一个全新的对象,彼此独立,不会相互影响
在实际编程中,根据需求选择合适的拷贝方式,以确保对象的属性被正确复制。