html5网站单页模板网站建设 账务处理
2026/3/19 10:37:19 网站建设 项目流程
html5网站单页模板,网站建设 账务处理,黄山旅游攻略及费用,农业推广项目❤ 写在前面 如果觉得对你有帮助的话#xff0c;点个小❤❤ 吧#xff0c;你的支持是对我最大的鼓励~ 个人独立开发wx小程序#xff0c;感谢支持#xff01;开篇故事#xff1a;为什么我的数据“打架”了#xff1f; 想象一下这个场景#xff1a;你在开发一个购物车功能…❤ 写在前面如果觉得对你有帮助的话点个小❤❤ 吧你的支持是对我最大的鼓励~个人独立开发wx小程序感谢支持开篇故事为什么我的数据“打架”了想象一下这个场景你在开发一个购物车功能复制了一个商品对象准备修改数量结果发现原始商品的数据也变了这种“灵异事件”让很多前端开发者头疼不已。letoriginalProduct{name:JavaScript高级程序设计,price:99,details:{publisher:人民邮电出版社,pages:728}};// 你以为的“复制”letcopiedProductoriginalProduct;copiedProduct.price79;// 修改副本的价格console.log(originalProduct.price);// 79原对象也被修改了这就是我们今天要解决的“深浅拷贝”问题下面让我们一步步解开这个谜团。内存模型理解深浅拷贝的基础在深入之前我们先看看JavaScript中数据是如何存储的┌─────────────┐ ┌───────────────┐ │ 栈内存 │ │ 堆内存 │ │ (Stack) │ │ (Heap) │ ├─────────────┤ ├───────────────┤ │ 基本类型 │ │ │ │ 变量名|值 │ │ 引用类型 │ │ a - 10 │ │ 的对象数据 │ │ b - true │ │ {name: xxx}│ │ │ │ [1,2,3] │ │ obj1 - ↗═══╪══════ {x: 1, y: 2} │ │ obj2 - ↗═══╪══════ {name: test}│ └─────────────┘ └───────────────┘基本类型Number, String, Boolean等直接存储在栈内存中而引用类型Object, Array等在栈中只存储地址指针真正的数据在堆内存中。深浅拷贝对比流程图原始对象选择拷贝方式浅拷贝深拷贝只复制第一层属性嵌套对象仍共享内存修改嵌套属性会影响原对象递归复制所有层级完全独立的新对象新旧对象互不影响适用场景简单数据结构适用场景复杂嵌套对象浅拷贝只挖第一层浅拷贝就像只复制房子的钥匙不复制房子里的家具。常见的浅拷贝方法方法1展开运算符最常用letshallowCopy{...originalObject};letshallowCopyArray[...originalArray];方法2Object.assign()letshallowCopyObject.assign({},originalObject);方法3数组的slice()和concat()letshallowCopyArrayoriginalArray.slice();letanotherCopyoriginalArray.concat();浅拷贝的陷阱letuser{name:小明,settings:{theme:dark,notifications:true}};letuserCopy{...user};userCopy.name小红;// ✅ 不会影响原对象userCopy.settings.themelight;// ❌ 原对象的theme也被修改了console.log(user.settings.theme);// light 中招了深拷贝连根拔起的复制深拷贝是真正的克隆创建一个完全独立的新对象。方法1JSON大法最简单但有局限letdeepCopyJSON.parse(JSON.stringify(originalObject));注意限制不能复制函数、undefined、Symbol不能处理循环引用Date对象会变成字符串方法2手写递归深拷贝函数functiondeepClone(obj,hashnewWeakMap()){// 处理基本类型和nullif(objnull||typeofobj!object){returnobj;}// 处理Dateif(objinstanceofDate){returnnewDate(obj);}// 处理数组if(Array.isArray(obj)){returnobj.map(itemdeepClone(item,hash));}// 处理普通对象if(hash.has(obj)){returnhash.get(obj);// 解决循环引用}letcloneObjObject.create(Object.getPrototypeOf(obj));hash.set(obj,cloneObj);for(letkeyinobj){if(obj.hasOwnProperty(key)){cloneObj[key]deepClone(obj[key],hash);}}returncloneObj;}// 测试letcomplexObj{name:测试,date:newDate(),nested:{x:1},arr:[1,2,[3,4]]};complexObj.selfcomplexObj;// 循环引用letcloneddeepClone(complexObj);console.log(cloned!complexObj);// trueconsole.log(cloned.nested!complexObj.nested);// trueconsole.log(cloned.selfcloned);// true循环引用正确处理方法3使用现成库// lodashimport_fromlodash;letdeepCopy_.cloneDeep(originalObject);// 或者使用structuredClone现代浏览器原生APIif(typeofstructuredClonefunction){letdeepCopystructuredClone(originalObject);}实战场景什么时候用什么拷贝场景1表单编辑推荐深拷贝// 编辑前深拷贝原始数据leteditDatadeepClone(originalData);// 用户随意编辑...editData.user.profile.avatarnew_avatar.jpg;// 点击取消原始数据完好无损// 点击保存提交editData场景2状态管理中的状态更新浅拷贝足够// Redux reducer中的状态更新functionreducer(stateinitialState,action){switch(action.type){caseUPDATE_SETTINGS:return{...state,// 浅拷贝settings:{...state.settings,// 嵌套对象也需要展开theme:action.payload}};// ...}}场景3配置对象合并浅拷贝深度合并functionmergeConfig(defaultConfig,userConfig){return{...defaultConfig,...userConfig,// 深度合并嵌套对象options:{...defaultConfig.options,...userConfig.options}};}性能考虑深浅拷贝的选择方法速度内存占用适用场景浅拷贝⚡⚡⚡⚡⚡快少简单对象无嵌套修改JSON深拷贝⚡⚡⚡中中数据简单无函数/日期递归深拷贝⚡⚡慢多复杂对象需要完整复制structuredClone⚡⚡⚡⚡较快中现代浏览器需要原生支持总结拷贝选择速查表只需要复制第一层数据→ 使用展开运算符...需要完全独立的副本→ 使用深拷贝数据简单不含函数/日期→JSON.parse(JSON.stringify())需要处理复杂类型和循环引用→ 手写递归或使用lodash现代浏览器环境→ 尝试structuredClone记住这个黄金法则当你不知道嵌套属性是否需要独立修改时选择深拷贝更安全互动挑战试试看你能看出下面代码的输出吗letpuzzle{a:1,b:{inner:2},c:[3,4]};letcopy1{...puzzle};letcopy2JSON.parse(JSON.stringify(puzzle));copy1.b.inner999;copy1.c.push(888);console.log(puzzle.b.inner);// 是多少console.log(puzzle.c.length);// 是多少console.log(copy2.b.inner);// 是多少答案第一个是999浅拷贝共享嵌套对象第二个是4数组也被修改了第三个是2深拷贝完全独立。希望这篇博客能帮你彻底理解JavaScript中的深浅拷贝下次遇到数据打架的情况你就知道该怎么处理了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询