返回

揭开JS手写深浅拷贝的奥秘|深入浅出解析差异与实践|揭秘浅拷贝的真面目

前端

正文

在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中对象拷贝的重要方式,它们在实现方式和应用场景上有着本质的区别。理解并正确使用浅拷贝和深拷贝,可以帮助我们避免常见的拷贝陷阱,并编写出更加健壮的代码。