对象、数组、函数等多种数据类型的深浅克隆(拷贝)
对象(数组)的深浅克隆
浅克隆
把
obj{ }
对象里面的所有属性拷贝到obj1{ }
中后,然后分别改变对象里面的变量,原始值互不影响,引用值一个改变,另一个跟着变。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 浅克隆
// a、d 原始值; b、c 引用值
let obj = {
a: 100,
b: [10, 20, 30],
c: {
x: 10
},
d: /^\d+$/
};
// let obj2 = {...obj};
let obj2 = {};
for (let key in obj) {
if (!obj.hasOwnProperty(key)) break;
obj2[key] = obj[key];
}
console.log(obj); // { a: 100, b: (3) [10, 20, 30], c: {x: 10}, d: /^\d+$/ }
console.log(obj2); // { a: 100, b: (3) [10, 20, 30], c: {x: 10}, d: /^\d+$/ }
obj2.a = 200;
obj2.b[0] = 55;
obj2.c["x"] = 66;
obj2.d = /^\d-$/;
console.log(obj); // { a: 100, b: (3) [55, 20, 30], c: {x: 66}, d: /^\d+$/ }
console.log(obj2); // { a: 200, b: (3) [55, 20, 30], c: {x: 66}, d: /^\d-$/ }
</script>
</body>
</html>
深克隆
修改引用值时,互不影响,你改我不变
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 深克隆
let obj = {
a: 100,
b: [10, 20, 30],
c: {
x: 10
},
d: /^\d+$/,
e : function() {
return 50;
},
f: new Date(),
g: new Map([["a", 1], ["b", 2], ["c", 3]]),
h: new Set([1, 2, 3, 3, 4, {a : 10}]),
i: null,
j: undefined
};
// 先转为字符串再转回对象的过程会重新开辟内存空间
// 日期,函数,正则在转为字符串时会出现问题
// 函数(不输出),正则(输出空对象),时间对象(输出时间字符串),Undefiend(不输出)
let obj2 = JSON.parse(JSON.stringify(obj));
obj2.b[0] = 22;
console.log(obj); // { a: 100, b: (3) [10, 20, 30], c: {x: 10}, d: /^\d+$/, e: ƒ e() }
console.log(obj2); // { a: 100, b: (3) [22, 20, 30], c: {x: 10}, d: {}, [[Prototype]]: Object }
function deepClone(obj) {
// 处理null
if (obj === null) return null;
// 处理原始值
if (typeof obj != "object" && typeof obj != "function") return obj;
// 处理函数
if (typeof obj === "function") {
let func = obj + ''
// 返回匿名函数
// new Function('...')() 直接执行引号中的内容,与eval
return new Function('return ' + func)();
}
// 处理正则
if (obj instanceof RegExp) {
return new RegExp(obj);
}
// 处理Set对象
if (obj instanceof Set) {
return new Set(obj);
}
// 处理Map对象
if (obj instanceof Map) {
return new Map(obj);
}
// 处理日期
if (obj instanceof Date) {
return new Date(obj);
}
// 用被克隆对象的构造函数创建一个实例,这样克隆出来的对象也是那个构造函数的实例,保持相同的所属类
let newObj = new obj.constructor;
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = deepClone(obj[key]);
}
}
return newObj;
}
let obj3 = deepClone(obj);
console.log(obj); // { a: 100, b: (3) [10, 20, 30], c: {x: 10}, d: /^\d+$/, e: ƒ e() }
console.log(obj3); // { a: 100, b: (3) [10, 20, 30], c: {x: 10}, d: /^\d+$/, e: ƒ e() }
console.log(obj === obj3); // false
console.log(obj.c === obj3.a); // false
console.log(obj.e === obj3.b); // false
console.log(obj.e === obj3.c); // false
console.log(obj.e === obj3.d); // false
console.log(obj.e === obj3.e); // false
console.log(obj.e === obj3.f); // false
console.log(obj.e === obj3.g); // false
console.log(obj.e === obj3.h); // false
console.log(obj.e === obj3.i); // false
console.log(obj.e === obj3.j); // false
</script>
</body>
</html>
本文作者:伏月廿柒
本文链接:https://www.cnblogs.com/by0627/p/16066576.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步