对于深拷贝,浅拷贝的概念很少说,概念能够自行百度哟!这里对深拷贝对象进行一些研究!数组
针对只有值的数据对象,下面一行代码足以!函数
JSON.parse(JSON.stringify(obj))
function clone(source) { var target = {}; for(var i in source) { if (source.hasOwnProperty(i)) { if (typeof source[i] === 'object') { target[i] = clone(source[i]); // 注意这里 } else { target[i] = source[i]; } } } return target; }
问题存在:code
function isObj(obj) { return (typeof obj === 'object' || typeof obj === 'function') && obj !== null } function deepCopy(obj) { let tempObj = Array.isArray(obj) ? [] :{}; for(let key in obj) { tempObj[key] = isObj(obj[key]) ? deepCopy(obj[key]) : obj[key]; } return tempObj; }
问题存在:对象
可使用一个WeakMap结构存储已经被拷贝的对象,每一次进行拷贝的时候就先向WeakMap查询该对象是否已经被拷贝,若是已经被拷贝则取出该对象并返回,将deepCopy函数改形成以下:原型链
function isObj(obj) { return (typeof obj === 'object' || typeof obj === 'function') && obj !== null } function deepCopy(obj, hash = new WeakMap()) { if(hash.has(obj)) return hash.get(obj) let cloneObj = Array.isArray(obj) ? [] : {} hash.set(obj, cloneObj) for (let key in obj) { cloneObj[key] = isObj(obj[key]) ? deepCopy(obj[key], hash) : obj[key]; } return cloneObj }
问题存在:get
const obj = { arr: [111, 222], obj: {key: '对象'}, a: () => {console.log('函数')}, date: new Date(), reg: /正则/ig} function isObj(obj) { return (typeof obj === 'object' || typeof obj === 'function') && obj !== null } function deepCopy(obj, hash = new WeakMap()) { let cloneObj; let Constructor = obj.constructor; switch(Constructor){ case RegExp: cloneObj = new Constructor(obj) break; case Date: cloneObj = new Constructor(obj.getTime()) break; case Function: cloneObj = eval(obj.toString()); break; default: if(hash.has(obj)) return hash.get(obj) cloneObj = new Constructor() hash.set(obj, cloneObj) } for (let key in obj) { cloneObj[key] = isObj(obj[key]) ? deepCopy(obj[key], hash) : obj[key]; } return cloneObj; } const cloneObj = deepCopy(obj); console.log(cloneObj);
更多遗留问题,针对函数进行拷贝,如果function,非箭头函数,如何解决?还有,若要拷贝原型链上的属性?如何拷贝不可枚举属性? 如何拷贝Error对象等等的坑?原型