揭开JS手写深浅拷贝的奥秘|深入浅出解析差异与实践|揭秘浅拷贝的真面目
2023-12-27 04:54:43
正文
在JavaScript的世界中,对象无处不在,因此,对象拷贝是开发人员经常需要面对的任务。JavaScript提供了两种对象拷贝的方式:深拷贝和浅拷贝。两者虽然都能够创建新对象的副本,但它们在实现方式和应用场景上却有着本质的区别。
浅拷贝
浅拷贝是指,一个新的对象对原始对象的属性值进行精确的拷贝,如果拷贝的是基本数据类型,拷贝的就是基本数值类型的值,如果是引用数据类型,拷贝的就是地址指针。这意味着,浅拷贝只会拷贝原始对象的第一层属性值,而不会递归地拷贝嵌套的对象。
举个例子,我们有一个名为“person”的对象,其中包含一个名为“name”的属性,其值为“John”。如果我们对“person”对象进行浅拷贝,则新创建的对象也会包含一个名为“name”的属性,其值为“John”。但是,如果“person”对象中包含一个名为“address”的属性,其值为一个对象,其中包含“street”和“city”两个属性,则浅拷贝不会拷贝“address”对象的这两个属性,新创建的对象中将不会包含“address”属性。
深拷贝
深拷贝是指,一个新的对象不仅拷贝原始对象的属性值,还会递归地拷贝嵌套的对象。这意味着,深拷贝会创建原始对象及其所有嵌套对象的副本。
还是以“person”对象为例,如果我们对“person”对象进行深拷贝,则新创建的对象不仅会包含一个名为“name”的属性,其值为“John”,还会包含一个名为“address”的属性,其值为一个对象,其中包含“street”和“city”两个属性。
浅拷贝与深拷贝的比较
特征 | 浅拷贝 | 深拷贝 |
---|---|---|
拷贝方式 | 只拷贝原始对象的属性值 | 递归地拷贝原始对象及其所有嵌套对象 |
拷贝深度 | 仅拷贝第一层属性值 | 拷贝所有层级的属性值 |
适用场景 | 基本数据类型和简单对象 | 复杂对象和嵌套对象 |
性能 | 性能优于深拷贝 | 性能逊于浅拷贝 |
内存占用 | 内存占用较少 | 内存占用较大 |
浅拷贝的实现
浅拷贝可以通过多种方式实现,最简单的方法是使用Object.assign()方法。Object.assign()方法可以将一个或多个源对象的属性值复制到目标对象。
const person = {
name: 'John',
address: {
street: 'Main Street',
city: 'New York'
}
};
const newPerson = Object.assign({}, person);
上述代码中,我们使用Object.assign()方法将“person”对象拷贝到“newPerson”对象。此时,“newPerson”对象将包含一个名为“name”的属性,其值为“John”,还会包含一个名为“address”的属性,其值为一个对象,其中包含“street”和“city”两个属性。但是,如果我们修改“newPerson”对象中的“address”属性,则不会影响“person”对象中的“address”属性。
深拷贝的实现
深拷贝可以通过多种方式实现,最简单的方法是使用JSON.parse()和JSON.stringify()方法。JSON.parse()方法可以将JSON字符串解析为JavaScript对象,JSON.stringify()方法可以将JavaScript对象转换为JSON字符串。
const person = {
name: 'John',
address: {
street: 'Main Street',
city: 'New York'
}
};
const newPerson = JSON.parse(JSON.stringify(person));
上述代码中,我们使用JSON.stringify()方法将“person”对象转换为JSON字符串,然后使用JSON.parse()方法将JSON字符串解析为“newPerson”对象。此时,“newPerson”对象将包含一个名为“name”的属性,其值为“John”,还会包含一个名为“address”的属性,其值为一个对象,其中包含“street”和“city”两个属性。如果我们修改“newPerson”对象中的“address”属性,则不会影响“person”对象中的“address”属性。
结语
浅拷贝和深拷贝都是JavaScript中对象拷贝的重要方式,它们在实现方式和应用场景上有着本质的区别。理解并正确使用浅拷贝和深拷贝,可以帮助我们避免常见的拷贝陷阱,并编写出更加健壮的代码。