// 深拷贝函数封装1 function deepCopy(obj) { // 根据obj的类型判断是新建一个数组还是对象 let newObj = Array.isArray(obj)? [] : {}; // 判断传入的obj存在,且类型为对象 if (obj && typeof obj === 'object') { for(key in obj) { // 如果obj的子元素是对象,则进行递归操作 if(obj[key] && typeof obj[key] ==='object') { newObj[key] = deepCopy(obj[key]) } else { // // 如果obj的子元素不是对象,则直接赋值 newObj[key] = obj[key] } } } return newObj // 返回新对象 } // 对象的深拷贝 let obj1 = { a: '1', b: '2', c: { name: 'Demi' } } let obj2 = deepCopy(obj1) //将obj1的数据拷贝到obj2 obj2.c.name = 'wilsunson' console.log(obj1) // {a: "1", b: "2", c: {name: 'wss'}} console.log(obj2) // {a: "1", b: "2", c: {name: 'wilsunson'}}
// 方法2
const objDeepClone = obj => { return clone(obj) } const isType = (obj, type) => { if (typeof obj !== 'object') return false; // 判断数据类型的经典方法: const typeString = Object.prototype.toString.call(obj); let flag; switch (type) { case 'Array': flag = typeString === '[object Array]'; break; case 'Date': flag = typeString === '[object Date]'; break; case 'RegExp': flag = typeString === '[object RegExp]'; break; default: flag = false; } return flag; }; /** * deep clone * @param {[type]} parent object 需要进行克隆的对象 * @return {[type]} 深克隆后的对象 */ const clone = parent => { // 维护两个储存循环引用的数组 const parents = [] const children = [] const _clone = parent => { if (parent === null) return null if (typeof parent !== 'object') return parent let child, proto if (isType(parent, 'Array')) { // 对数组做特殊处理 child = [] } else if (isType(parent, 'RegExp')) { // 对正则对象做特殊处理 child = new RegExp(parent.source, getRegExp(parent)) if (parent.lastIndex) child.lastIndex = parent.lastIndex } else if (isType(parent, 'Date')) { // 对Date对象做特殊处理 child = new Date(parent.getTime()) } else { // 处理对象原型 proto = Object.getPrototypeOf(parent) // 利用Object.create切断原型链 child = Object.create(proto) } // 处理循环引用 const index = parents.indexOf(parent) if (index !== -1) { // 如果父数组存在本对象,说明之前已经被引用过,直接返回此对象 return children[index] } parents.push(parent) children.push(child) for (const i in parent) { // 递归 child[i] = _clone(parent[i]) } return child } return _clone(parent) } console.log(objDeepClone({ name: '张三', age: 23, obj: { name: '李四', age: 46}, arr:[1,2,3] })) /
更简单的??
function copy(obj, appeard = new Map()) { if (!(obj instanceof Object)) return obj // 原始数据类型 if (appread.has(obj)) return appeard.get(obj) // 重复引用 let result = Array.isArray(obj) ? [] : {} appeard.set(obj, result) // 将对象存入map // 遍历所有属性进行递归拷贝 ;[...Object.keys(obj), ...Object.getOwnPropertySymbols(obj)].forEach(key => { result[key] = copy(obj[key], appeard) }) return result }