<!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>