什么是JavaScript中的淺層拷貝和深層拷貝?

var employee = {eid: "E102",ename: "Jack",eaddress: "New York",salary: 50000}console.log("Employee=> ", employee);var newEmployee = employee; // Shallow copyconsole.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.
輸出:

說(shuō)明:從上面的示例中可以看出,當(dāng)newEmployee的名稱被修改時(shí),它也反映在舊的employee對(duì)象上。這可能會(huì)導(dǎo)致數(shù)據(jù)不一致。這稱為淺拷貝。新創(chuàng)建的對(duì)象與舊對(duì)象具有相同的內(nèi)存地址。
因此,對(duì)它們中的任何一個(gè)所做的任何更改都會(huì)更改兩者的屬性。為解決此問(wèn)題,使用了深拷貝。如果將其中一個(gè)從內(nèi)存中刪除,則另一個(gè)將不復(fù)存在。從某種意義上說(shuō),這兩個(gè)對(duì)象是相互依存的。
深層拷貝:與淺層拷貝不同,深層拷貝會(huì)復(fù)制舊對(duì)象的所有成員,為新對(duì)象分配單獨(dú)的內(nèi)存位置,然后將復(fù)制的成員分配給新對(duì)象。
這樣,兩個(gè)對(duì)象彼此獨(dú)立,并且在對(duì)任何一個(gè)對(duì)象進(jìn)行任何修改的情況下,另一個(gè)對(duì)象均不受影響。
同樣,如果刪除了其中一個(gè)對(duì)象,則另一個(gè)仍保留在內(nèi)存中?,F(xiàn)在,要在JavaScript中創(chuàng)建對(duì)象的深層副本,我們使用JSON.parse()和JSON.stringify()方法。讓我們以一個(gè)例子來(lái)更好地理解它。
例子代碼:
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);
輸出:

說(shuō)明:在這里,新對(duì)象是使用JavaScript的JSON.parse()和JSON.stringify()方法創(chuàng)建的。JSON.stringify()將JavaScript對(duì)象作為參數(shù),然后將其轉(zhuǎn)換為JSON字符串。
將此JSON字符串傳遞給JSON.parse()方法,然后將其轉(zhuǎn)換為JavaScript對(duì)象。
當(dāng)對(duì)象較小且具有可序列化的屬性時(shí),此方法很有用。但是,如果對(duì)象很大并且包含某些不可序列化的屬性,則存在數(shù)據(jù)丟失的風(fēng)險(xiǎn)。
特別是如果對(duì)象包含方法,則JSON.stringify()將失敗,因?yàn)榉椒ú豢尚蛄谢?。有更好的方法可以深度克隆其中的一種,即Lodash,它也允許克隆方法。
Lodash到Deep Copy:?Lodash是一個(gè)JavaScript庫(kù),提供了多個(gè)實(shí)用程序功能,而Lodash庫(kù)中最常用的功能之一是cloneDeep()方法。此方法有助于深度克隆對(duì)象,還可以克隆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());
輸出:

說(shuō)明:修改后,兩個(gè)對(duì)象都具有不同的屬性。同樣,每個(gè)對(duì)象的方法定義不同,并產(chǎn)生不同的輸出。

