手写JS深拷贝
<!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>JS深拷贝</title> </head> <body> </body> <script> let obj = { name: '张三', age:22, arr: [1,2,'dadas'], where: { country1: '中国', country2: '府谷', } } function deepClone(obj) { if(obj === null || typeof obj !== 'object') { return obj; } let result; if(obj instanceof Array) { result = [] } else { result = {} } for(let key in obj) { if(obj.hasOwnProperty(key)) { result[key] = deepClone(obj[key]) } } return result } let newObj = deepClone(obj); console.log(newObj); newObj.name = 999; console.log(newObj); console.log(obj); </script> </html>
方法二:
- 函数 正则 日期 ES6新对象 等不是直接返回其地址,而是重新创建
- 需要避免出现循环引用的情况
const _completeDeepClone = (target, map = new WeakMap()) => { // 基本数据类型,直接返回 if (typeof target !== 'object' || target === null) return target // 函数 正则 日期 ES6新对象,执行构造题,返回新的对象 const constructor = target.constructor if (/^(Function|RegExp|Date|Map|Set)$/i.test(constructor.name)) return new constructor(target) // map标记每一个出现过的属性,避免循环引用 if (map.get(target)) return map.get(target) map.set(target, true) const cloneTarget = Array.isArray(target) ? [] : {} for (prop in target) { if (target.hasOwnProperty(prop)) { cloneTarget[prop] = _completeDeepClone(target[prop], map) } } return cloneTarget }