浅拷贝
Object.assignlet obj = {a:1,b:{c:3}} let obj1 = Object.assign(obj) obj1.b.c = '哈哈' console.log(obj, obj1)- 拓展运算符
let obj = {a:1,b:{c:3}} let obj1 = {...obj} obj1.b.c = '哈哈' console.log(obj, obj1) concat(只针对数组)let arr = [{name:"Livia"},{name:"David"},{name:"Frank"}] let arr1 = arr.concat() arr1[2].name += "!!" console.log(arr, arr1)slice(只针对数组)let arr = [{name:"Livia"},{name:"David"},{name:"Frank"}] let arr1 = arr.slice() arr1[2].name += "!!" console.log(arr, arr1)
深拷贝
-
JSON.stringify -
第三方库,lodash._cloneDeep()
-
简易递归
function myDeep(obj) { let res = {} for (let key in obj) { if(typeof obj[key] !== 'object' && obj[key] !== null){ res[key] = obj[key] } else { res[key] = myDeep(obj[key]) } } return res } let obj = { a: 1, b: { c: 3, } } let obj1 = myDeep(obj) obj1.b.c = 666 console.log(obj, obj1) -
持续完善版 上述的简易版存在以下问题:
- 无法正确复制不可枚举属性
- 使用
Reflect.ownKeys解决
- 使用
- 只能正确复制基础数据类型,而对于Array、Function等无法正确复制
- 当遇到Date、RegExp等实例,重新生成对应实例
- 循环引用问题
- weakMap作为hash表,可以解决弱引用问题(挖个坑🕳)
制造难题
let obj = { num: 0, str: 'haha', bool: true, unf: undefined, nul: null, obj: { name:"Frank" }, arr: [5,6,7], func: function() {console.log("Hello, Frank")}, date: new Date(0), reg: new RegExp('/正则/ig'), [Symbol('1')]: 1, } Object.defineProperty(obj, 'innumerable', { enumerable: false, value: '不可枚举' }) obj.loop = obj console.log(obj)改良版(有bug,下次再改)
let obj = { num: 0, str: 'haha', bool: true, unf: undefined, nul: null, obj: { name:"Frank" }, arr: [5,6,7], func: function() {console.log("Hello, Frank")}, date: new Date(0), reg: new RegExp('/正则/ig'), [Symbol('1')]: 1, } Object.defineProperty(obj, 'innumerable', { enumerable: false, value: '不可枚举' }) obj.loop = obj function deepPlus(obj, map = new WeakMap()) { let res = {} if(obj instanceof RegExp){ return new RegExp(obj) } if(obj instanceof Date){ return new Date(obj) } if(map.has(obj)) { return map.get(obj) } let allDesc = Object.getOwnPropertyDescriptors(obj) map.set(obj, allDesc) for (let key of Reflect.ownKeys(obj)) { console.log('key', key, typeof obj[key]) if(typeof obj[key] === 'object' && obj[key] !== null){ res[key] = deepPlus(obj[key], map) } else { res[key] = obj[key] } } return res } let obj1 = deepPlus(obj) console.log("obj", obj) console.log("obj1", obj1) - 无法正确复制不可枚举属性