// 深拷贝函数封装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 }