JavaScript 开发 - Object 的 assign 方法,以及深拷贝解决方案

张开发
2026/6/12 13:15:25 15 分钟阅读
JavaScript 开发 - Object 的 assign 方法,以及深拷贝解决方案
Object 的 assign 方法以及深拷贝解决方案1、基本介绍Object 的 assign 方法只进行浅拷贝constoriginal{name:zs,age:20,friend:{name:ls,age:25,},};constcloneObject.assign({},original);original.friend.age26;console.log(original.friend.age);console.log(clone.friend.age);# 输出结果 26 262、深拷贝解决方案JSON 序列化有局限性constoriginal{name:zs,age:20,friend:{name:ls,age:25,},};constcloneJSON.parse(JSON.stringify(original));original.friend.age26;console.log(original.friend.age);console.log(clone.friend.age);# 输出结果 26 25使用 structuredClone 方法它是 JavaScript 中用于深拷贝对象的内置方法constoriginal{name:zs,age:20,friend:{name:ls,age:25,},};constclonestructuredClone(original);original.friend.age26;console.log(original.friend.age);console.log(clone.friend.age);# 输出结果 26 25手动实现深拷贝函数constoriginal{name:zs,age:20,friend:{name:ls,age:25,},};functiondeepAssign(target,...sources){// 边界处理target 必须为对象if(targetnull||typeoftarget!object){target{};}// 使用 WeakMap 记录已合并的对象处理循环引用constseennewWeakMap();functionisObject(item){returnitemtypeofitemobject!Array.isArray(item);}functionmerge(targetObj,sourceObj,parentKey){if(!sourceObj||typeofsourceObj!object){returntargetObj;}// 处理循环引用if(seen.has(sourceObj)){returnseen.get(sourceObj);}seen.set(sourceObj,targetObj);// 处理数组复制数组但不保留引用if(Array.isArray(sourceObj)){if(!Array.isArray(targetObj)){targetObj[];}// 确保目标数组长度足够for(leti0;isourceObj.length;i){if(iinsourceObj){if(isObject(sourceObj[i])||Array.isArray(sourceObj[i])){targetObj[i]merge(targetObj[i],sourceObj[i],${parentKey}[${i}]);}else{targetObj[i]sourceObj[i];}}}returntargetObj;}// 处理普通对象if(isObject(sourceObj)){if(!isObject(targetObj)){targetObj{};}constkeys[...Object.keys(sourceObj),...Object.getOwnPropertySymbols(sourceObj)];for(constkeyofkeys){constsourceValsourceObj[key];if(sourceValundefined)continue;if(isObject(sourceVal)||Array.isArray(sourceVal)){// 递归合并子属性targetObj[key]merge(targetObj[key],sourceVal,${parentKey}.${String(key)});}else{// 直接赋值targetObj[key]sourceVal;}}returntargetObj;}returntargetObj;}// 依次合并每个源对象for(constsourceofsources){if(sourcenull)continue;merge(target,source);}returntarget;}constclonedeepAssign({},original);original.friend.age26;console.log(original.friend.age);console.log(clone.friend.age);# 输出结果 26 25

更多文章