农村网站平台建设方案,国内优秀网页设计赏析,玉林住房和城乡建设部网站,wordpress替换dede理解深浅拷贝
深浅拷贝问题的出现是由于JavaScript对不同类型的存储方式而引发的。 对于原始数据类型#xff0c;它们的值是直接存储在栈内存中#xff1b; 而复杂数据类型#xff0c;则在栈内存中记录它的指针#xff0c;而指针指向堆内存中真正的值。 所以对于原始数据类…理解深浅拷贝
深浅拷贝问题的出现是由于JavaScript对不同类型的存储方式而引发的。 对于原始数据类型它们的值是直接存储在栈内存中 而复杂数据类型则在栈内存中记录它的指针而指针指向堆内存中真正的值。 所以对于原始数据类型就没有深浅拷贝一说而对于复杂数据类型浅拷贝就是仅复制指针但被复制对象改变时新复制的对象也会跟着改变深拷贝则是连同堆内存中的数据完全拷贝一份新旧对象的变化互不影响。
深浅拷贝的定义
浅拷贝 拷贝复杂类型时仅拷贝对象的指针当原对象改变时拷贝对象也会跟着改变。 深拷贝 拷贝复制类型时拷贝对象的值当原对象改变时拷贝对象不会跟着改变。 深浅拷贝的实现方案
浅拷贝方案:
展开运算符(ES6)Object.assign()concat…
深拷贝:
手写递归JSON.parse(JSON.stringfy()) 先转换成字符串再解析回对象缺点是不能处理正则表达式和函数等特殊数据类型 一些库封装的深拷贝方法例如Lodash的_.cloneDeep()
手写实现
// 先写一个浅拷贝
function _deepClone(target) {let cloneRes {};for(const key in target) {cloneRes[key] target[key]}return cloneRes// 函数出口// if (typeof target ! obejct) return target
}// 2. 普通深拷贝(只考虑对象/非对象)
function _deepClone(target) {if (typeof target object){// 如果是对象进行处理let cloneRes {};for(const key in target) {cloneRes[key] _deepClone(target[key])}return cloneRes} else {// 如果不是对象直接返回return target}
}// 3.考虑数组的深拷贝
function _deepClone(target) {if (typeof target object) {let cloneRes Array.isArray(target) ? [] : {}; // 核心for (const key in target) {cloneRes[key] _deepClone(target[key])}return cloneRes} else {return target}
}// 4. 考虑循环引用
// Q为什么要用WeakMap替代Map?
// A强引用和弱引用的区别强引用只能手动释放弱引用能够被垃圾回收机制释放使用Map会造成内存额外消耗。
// WeakMap中的键是弱引用Map中的键是强引用
function _deepClone(target, mapnew WeakMap()) {if (typeof target object) {let cloneRes Array.isArray(target) ? [] : {}; // 核心// 防止循环调用导致的栈内存溢出if (map.get(target)) {return map.get(target)}map.set(target, cloneRes)for (const key in target) {cloneRes[key] _deepClone(target[key], map)}return cloneRes} else {return target}
}// 5. 考虑其他数据类型
function _deepClone (target, map new WeakMap()) {if (target null) return nullif (target instanceof Date) return new Date(target)if (target instanceof RegExp) return new RegExp(target);if (typeof target ! object) return targetif (map.get(target)) return map.get(target);let cloneRes new target.constructor()map.set(target, cloneRes)for (const key in target) {if (target.hasOwnProperty(key)) {cloneRes[key] _deepClone(target[key], map);}}return cloneRes
}
// 6. 性能优化
// 把for..in改为普通的for循环性能会有所提高// 测试案例
const target {field1: 1,field2: undefined,field3: {child: child},field4: [2, 4, 8]
};
const newTarget _deepClone(target)
newTarget.field4[1] Child2
console.log(target);
console.log(newTarget);
console.log(target newTarget);
// 输出
// {
// field1: 1,
// field2: undefined,
// field3: { child: child },
// field4: [ 2, 4, 8 ]
// }
// {
// field1: 1,
// field2: undefined,
// field3: { child: child },
// field4: [ 2, Child2, 8 ]
// }
// false
参考链接相关文章
前端早读课【第2810期】JavaScript 深拷贝性能分析