JavaScript 实现自定义函数进行深度克隆
通常,克隆意味着将一个值复制到另一个值。在JavaScript中,有两种类型的克隆,即 深度克隆 和 浅克隆 。本文讨论深度克隆并了解深度克隆。
克隆是一个概念,可以在任何数据类型中发生,可以是原始数据类型(如字符串、数字)或复合数据类型(如数组和JavaScript对象)。
深度克隆: 深度克隆是一种技术,用于在JavaScript中克隆数组和对象时复制所有内容,以避免数据丢失。
示例1: 如下例所示,如果我们更改一个对象的值,那么其他对象也会反映这个变化,这是导致此问题的原因,为了避免这个问题,我们使用深度克隆。
Javascript
var obj1 = {
name: "Geeks",
company: "Gfg"
}
var obj2 = obj1;
obj1.name = "GeeksForGeeks"
console.log("First name is", obj1.name)
console.log("Second name is ", obj2.name);
输出:
First name is GeeksForGeeks
Second name is GeeksForGeeks
示例2: 如下示例所示,如果我们更改一个对象的值,则会导致数据损坏,其反映在其他对象中。
Javascript
var employee = {
eid: "E102",
ename: "Jack",
eaddress: "New York",
salary: 50000
}
var newEmployee = employee;
newEmployee.ename = "Beck";
console.log("New Employee", newEmployee);
console.log("Old Employee", employee);
输出:
New Employee, {
eid: 'E102',
ename: 'Beck',
eaddress: 'New York',
salary: 50000
}
Old Employee, {
eid: 'E102',
ename: 'Beck',
eaddress: 'New York',
salary: 50000
}
方法: 现在我们将创建一个自己的自定义函数来深度克隆一个对象。
- 我们将创建一个名为 deepCopy 的函数,它将接受一个需要创建深拷贝的对象作为输入,并返回一个深度复制的对象。
- 我们将声明一个名为 result 的对象,它将存储最终的输出结果。
- 检查输入的对象是否是:
- null、undefined、数组、函数或不是对象类型(例如字符串、布尔值或数字)。如果是,则简单地返回输入。
- 如果输入的是对象类型,则使用 Object.keys 方法获取对象的键,并对每个键再次调用 deepCopy 函数。
- 返回 result 。
示例: 这个示例展示了上述方法的使用。
JavaScript
// Declare object to be cloned
const obj = {
name: {
firstName: "alice",
lastName: null
},
address: {
number: 12345,
country: "London",
pincode: 208027
},
email: "foo@bar.com",
hobbies: ["singing", "dancing", "music"],
}
// Declare object to be cloned
const objTwo = {
a: null,
b: true
}
// Function to deep copy an existing object
// and return new object
function deepCopy(obj) {
// Declare object which will store the output
const result = {};
// If the object isnt of type object or
// object is null, undefined, is an Array
// or a function then no need to iterate
// over it and simply return it
if (typeof obj !== "object" ||
typeof obj === undefined ||
obj === null ||
Array.isArray(obj) ||
typeof obj == "function") {
return obj;
}
// Store the keys of the object
const keys = Object.keys(obj);
// Iterate through the keys of the
// object retrieved above
for (let key in keys) {
// Recursively iterate through each of the key.
result[keys[key]] = deepCopy(obj[keys[key]])
}
return result;
}
const deepCopiedObject = deepCopy(obj)
const deepCopiedObjectTwo = deepCopy(objTwo);
// Modifying property country
obj.address.country = "india"
console.log(deepCopiedObject)
console.log(obj)
objTwo.a = "gfg";
console.log(deepCopiedObjectTwo)
console.log(objTwo)
输出:
{
name: { firstName: 'alice', lastName: null },
address: {
number: 12345,
country: 'London',
pincode: 208027
},
email: 'foo@bar.com',
hobbies: ['singing', 'dancing', 'music']
}
{
name: { firstName: 'alice', lastName: null },
address: {
number: 12345,
country: 'india',
pincode: 208027
},
email: 'foo@bar.com',
hobbies: ['singing', 'dancing', 'music']
}
{ a: null, b: true }
{ a: 'gfg', b: true }
解释: 即使修改了 obj ,数据仍然安全地存储在 deepCopiedObject 和 deepCopiedObjectTwo 中,并且不发生变异。