<!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 = {
name: 'zjh',
gender: 'man',
friend: {
girl: 'lsq'
}
}
function deepClone(data, map = new Map()){
//判断数据是不是引用类型,如果是引用类型可以直接将值return
if(typeof data !== 'object'){
return data
}
//存下参数 data 是否时数组的判断,用于再下面遍历的时候使用合适的遍历方式
let isArray = Array.isArray(data)
//引用类型的数据则开始深拷贝
//判断传递过来的数据是数组还是对象,数组就将 clone 写为数组类型,负责写为普通对象类型
let clone = Array.isArray(data) ? [] : {}
//甄别这个属性有没有已经被克隆下来,避免死循环,如果已经被克隆下来就返回该属性之前存下的值
if(map.get(data)){
return map.get(data)
}
//如果没有被克隆过,则将 clone 对象保存下来,用于递归时甄别使用
map.set(data, clone)
//如果参数 data 不是数组就将属性名给保存下来
let keys = isArray? null: Object.keys(data)
for (let key in data) {
//这里有可能存在多层引用数据类型数据嵌套,所以使用递归调用
clone[key] = deepClone(data[key])
}
return clone
}
let newObj = deepClone(obj)
newObj.name = 'zzz'
newObj.friend.girl = 'lll'
console.log('clone', newObj);
console.log('initial', obj);
</script>
</body>
</html>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。