<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>对数据实现深克拷贝</title>
</head>
<body>
<script>
var obj1 = {
xueshiyang: {
father: {
xuesongpo: {
father: {
xuexieqing: {
father: [{
sex: "woman"
}, {
name: "i donot know"
}, {}]
}
}
}
}
}
}
//思路:判断第一个参数是不是可遍历的,如果可以遍历递归调用函数本身,否则就返回第一个参数
function deepClone(initObj, finalObj) {
var obj = finalObj || {};
if(initObj.constructor==Object||initObj.constructor==Array){
for (var i in initObj) {
obj[i] = (initObj[i].constructor === Array) ? [] : {};
deepClone(initObj[i], obj[i])
}
}else{
obj=initObj;
}
return obj;
}
var newData = deepClone(obj1);
newData.name="xueshiyang";
console.log(newData,obj1);//深拷贝的数据不会影响原数据
//思路: 把对象中的keys遍历出来,之后再根据键名来判断键值是否有继续递归的必要
function deepData(data) {
let result, keys;
if (typeof data == 'object' && data != null) {
keys = Object.keys(data);
if (Array.isArray(data)) {
result = [];
} else if (data.constructor === Object) {
result = {};
}
keys.forEach((item) => {
if (data[item].constructor == Array || data[item].constructor == Object) {
result[item] = data[item];
deepData(result[item]);
} else {
result[item] = data[item]
}
})
}
return result;
}
var cc = deepData(obj1)
cc.test = 'i just wanted test the example'
console.log(cc, obj1)
// 数据是数组或者是对象,才可以对数据进行for in循环和递归调用(在递归调用中判断数据是否可以遍历和第一个方法相似)
function deepCopy(arr) {
var obj = arr.constructor == Array ? [] : {};
if (arr.constructor == Array || arr.constructor == Object) {
for (var item in arr) {
obj[item] = deepCopy(arr[item]);
}
} else {
obj = arr;
}
return obj;
}
var dd = deepCopy(obj1);
dd.sex = "ehhehehe"
console.log(dd, obj1)
</script>
</body>
</html>