什么是JavaScript中的浅层拷贝和深层拷贝?

 

JavaScript是一种高级的,动态类型化的客户端脚本语言。JavaScript为静态HTML页面添加了很多功能。像大多数其他编程语言一样,JavaScript允许支持深层复制和浅层复制的概念。 浅层拷贝:当使用赋值运算符将参考变量复制到新的参考变量中时,将创建所引用对象的浅表副本。简而言之,引用变量主要存储它引用的对象的地址。为新参考变量分配旧参考变量的值后,将存储在旧参考变量中的地址复制到新参考变量中。这意味着旧参考变量和新参考变量都指向内存中的同一对象。如果对象的状态通过任何参考变量发生变化,则两者都会反映出来。让我们通过一个例子来更好地理解它。例子代码:

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
var employee = {     eid: "E102",     ename: "Jack",     eaddress: "New York",     salary: 50000 } console.log("Employee=> ", employee); var newEmployee = employee;    // Shallow copy console.log("New Employee=> ", newEmployee); console.log("---------After modification----------"); newEmployee.ename = "Beck"; console.log("Employee=> ", employee); console.log("New Employee=> ", newEmployee); // Name of the employee as well as  // newEmployee is changed. 

输出:

说明:从上面的示例中可以看出,当newEmployee的名称被修改时,它也反映在旧的employee对象上。这可能会导致数据不一致。这称为浅拷贝。新创建的对象与旧对象具有相同的内存地址。

因此,对它们中的任何一个所做的任何更改都会更改两者的属性。为解决此问题,使用了深拷贝。如果将其中一个从内存中删除,则另一个将不复存在。从某种意义上说,这两个对象是相互依存的。

深层拷贝:与浅层拷贝不同,深层拷贝会复制旧对象的所有成员,为新对象分配单独的内存位置,然后将复制的成员分配给新对象。

这样,两个对象彼此独立,并且在对任何一个对象进行任何修改的情况下,另一个对象均不受影响。

同样,如果删除了其中一个对象,则另一个仍保留在内存中。现在,要在JavaScript中创建对象的深层副本,我们使用JSON.parse()和JSON.stringify()方法。让我们以一个例子来更好地理解它。

例子代码:

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
var employee = {     eid: "E102",     ename: "Jack",     eaddress: "New York",     salary: 50000 } console.log("=========Deep Copy========"); var newEmployee = JSON.parse(JSON.stringify(employee)); console.log("Employee=> ", employee); console.log("New Employee=> ", newEmployee); console.log("---------After modification---------"); newEmployee.ename = "Beck"; newEmployee.salary = 70000; console.log("Employee=> ", employee); console.log("New Employee=> ", newEmployee); 

输出:

说明:在这里,新对象是使用JavaScript的JSON.parse()和JSON.stringify()方法创建的。JSON.stringify()将JavaScript对象作为参数,然后将其转换为JSON字符串。

将此JSON字符串传递给JSON.parse()方法,然后将其转换为JavaScript对象。

当对象较小且具有可序列化的属性时,此方法很有用。但是,如果对象很大并且包含某些不可序列化的属性,则存在数据丢失的风险。

特别是如果对象包含方法,则JSON.stringify()将失败,因为方法不可序列化。有更好的方法可以深度克隆其中的一种,即Lodash,它也允许克隆方法。

Lodash到Deep Copy: Lodash是一个JavaScript库,提供了多个实用程序功能,而Lodash库中最常用的功能之一是cloneDeep()方法。此方法有助于深度克隆对象,还可以克隆JSON.stringify()方法的局限性,即不可序列化的属性。

代码:

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
const lodash = require("lodash"); var employee = {     eid: "E102",     ename: "Jack",     eaddress: "New York",     salary: 50000,     details: function () {         return "Employee Name: "             + this.ename + "-->Salary: "             + this.salary;     } } var deepCopy = lodash.cloneDeep(employee); console.log("Original Employee Object"); console.log(employee); console.log("Deep Copied Employee Object"); console.log(deepCopy); deepCopy.eid = "E103"; deepCopy.ename = "Beck"; deepCopy.details = function () {     return "Employee ID: " + this.eid          + "-->Salary: " + this.salary; } console.log("----------After Modification----------"); console.log("Original Employee Object"); console.log(employee); console.log("Deep Copied Employee Object"); console.log(deepCopy); console.log(employee.details()); console.log(deepCopy.details()); 

输出:

说明:修改后,两个对象都具有不同的属性。同样,每个对象的方法定义不同,并产生不同的输出。

本文完〜

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。

http://image98.pinlue.com/thumb/img_jpg/eXCSRjyNYcalkicDT5GDpw409j9qZm6duvAouaC1OtRP5H57FfrZ1FTZ1ZxdsLTLvJTyTCoGtajUqOJ5CWMjDXw/0.jpeg
分享
评论
首页