什么是深拷贝?
对于引用类型的数据,才有深浅拷贝的说法
- 浅拷贝 :执行拷贝的变量只复制被拷贝变量内存的引用数据的地址。
被拷贝变量内地址指向的数据发生变化时,执行拷贝的变量也会同步改变
- 深拷贝:
- 在堆内存中开辟一个全新的存储空间
- 将被拷贝变量中引用地址对应的内容完整复制一份存入新的存储空间
- 将新的存储空间的地址存入执行拷贝的变量中。
被拷贝变量内地址指向的数据发生变化时,执行拷贝的变量不会改变
深拷贝方案一 JSON.parse(JSON.stringify(obj))
缺陷:
- 属性值为函数和undefined的属性会丢失
- 属性值为正则表达式的会变成{}
- 属性值为时间对象的会变成时间字符串
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
let obj = {
string: "字符串",
Number: 10,
null: null,
undefined: undefined,
date: new Date(),
function: () => {
console.log("函数");
},
RegExp: /^([0]{2}|0[1-9]|[1-9])\d*$/,
}
console.log("被拷贝的对象");
console.log(obj);
let objJSONclone = JSON.parse(JSON.stringify(obj));
console.log("使用JSON.parse(JSON.stringify(obj))拷贝对象");
console.log(objJSONclone);
</script>
</body>
</html>
深拷贝方案二
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
/**
* 深拷贝
* @param {Object} obj 要拷贝的对象
*/
let obj = {
string: "字符串",
Number: 10,
null: null,
undefined: undefined,
date: new Date(),
function: () => {
console.log("函数");
},
RegExp: /^([0]{2}|0[1-9]|[1-9])\d*$/,
}
function deepClone(obj) {
if (obj === null) return null;
if (typeof obj !== "object") return obj;
if (obj.constructor === Date) return new Date(obj);
if (obj.constructor === RegExp) return new RegExp(obj);
var newObj = new obj.constructor(); //保持继承链
for (var key in obj) {
//不遍历其原型链上的属性
if (obj.hasOwnProperty(key)) {
var val = obj[key];
// 使用arguments.callee解除与函数名的耦合
newObj[key] = typeof val === "object" ? arguments.callee(val) : val;
}
}
return newObj;
}
let test = deepClone(obj)
console.log(test)
</script>
</body>
</html>