基于MCP协议与AI Agent构建AIoT智能体:从原理到实战
2026/8/7 13:20:36
欢迎使用我的小程序👇👇👇👇 俱好用助手功能介绍
想象一下,你有一本心爱的精装书,朋友想借去阅读。你有两个选择:
在JavaScript的世界里,拷贝数据就像这个场景,但有更多的“套娃”情况!
浅拷贝就像只搬走了家具,但墙上还挂着原房子的钥匙:
// 原始对象 - 一个“套娃”对象constoriginal={name:"小明",age:25,hobbies:["编程","游戏","阅读"],// 注意这个数组!address:{city:"北京",district:"海淀区"}};// 浅拷贝的几种方式:constshallowCopy1=Object.assign({},original);constshallowCopy2={...original};// 扩展运算符constshallowCopy3=original.slice?.();// 数组专用// 试试修改会发生什么?shallowCopy1.name="小红";// ✅ 不会影响originalshallowCopy1.hobbies.push("摄影");// ⚠️ 糟糕!original的hobbies也被改了!浅拷贝的特点:
深拷贝就像带着所有家当搬到了全新的房子:
// 深拷贝实现方式大比拼// 方法1:JSON大法(最简单但有局限)constdeepCopy1=JSON.parse(JSON.stringify(original));// 方法2:递归实现(自己动手,丰衣足食)functiondeepClone(obj){if(obj===null||typeofobj!=='object')returnobj;if(objinstanceofDate)returnnewDate(obj);if(objinstanceofRegExp)returnnewRegExp(obj);constclone=Array.isArray(obj)?[]:{};for(letkeyinobj){if(obj.hasOwnProperty(key)){clone[key]=deepClone(obj[key]);}}returnclone;}constdeepCopy2=deepClone(original);// 方法3:使用现成库(最省心)// const deepCopy3 = _.cloneDeep(original); // Lodash// const deepCopy4 = structuredClone(original); // 现代JS原生API现在无论怎么修改deepCopy,都不会影响original了!
// 场景1:配置合并constdefaultConfig={theme:'light',showTips:true};constuserConfig={theme:'dark'};constfinalConfig={...defaultConfig,...userConfig};// 场景2:创建对象副本进行简单修改constuser={name:'张三',loggedIn:false};constupdatedUser={...user,loggedIn:true};// 场景1:状态管理(如Redux reducer)functionreducer(state,action){switch(action.type){case'UPDATE_USER':return{...state,user:deepClone(action.payload)// 确保完全独立};}}// 场景2:表单数据的初始副本constinitialFormData=deepClone(templateData);constformData=deepClone(initialFormData);// 每次都是新的开始// 陷阱1:循环引用(自己引用自己)constnarcissist={name:"自恋对象"};narcissist.self=narcissist;// 我引用我自己!// JSON大法会报错!// JSON.parse(JSON.stringify(narcissist)); // TypeError!// 陷阱2:特殊对象constspecialObj={date:newDate(),regex:/hello/gi,func:function(){return"Hi";},undefined:undefined,infinity:Infinity,nan:NaN};console.log(JSON.parse(JSON.stringify(specialObj)));// 函数、undefined不见了!日期变成了字符串...| 方法 | 速度 | 深度 | 特殊类型支持 | 循环引用支持 |
|---|---|---|---|---|
扩展运算符... | ⚡⚡⚡⚡⚡ | 浅 | 有限 | ❌ |
Object.assign() | ⚡⚡⚡⚡⚡ | 浅 | 有限 | ❌ |
| JSON方法 | ⚡⚡⚡ | 深 | 差 | ❌ |
| 递归实现 | ⚡⚡ | 深 | 好 | ❌ |
| Lodash的cloneDeep | ⚡⚡ | 深 | 很好 | ✅ |
structuredClone() | ⚡⚡⚡ | 深 | 较好 | ✅ |
“先问要不要,再问怎么做”- 先确定是否需要深拷贝,很多情况浅拷贝就够用了
现代JS的救星:
// 浏览器和Node.js的新宠constcloned=structuredClone(original);// 支持大部分类型!Lodash是你的好朋友:
import{cloneDeep}from'lodash-es';// 按需引入// 或者用 throttle 的深拷贝函数性能提示:对于超大对象,考虑是否需要整个拷贝,也许只需修改部分
// 购物车场景constshoppingCart={items:[{id:1,name:"JavaScript高级编程",quantity:1,price:99},{id:2,name:"TypeScript入门",quantity:2,price:79}],discount:0.1,getTotal(){returnthis.items.reduce((sum,item)=>sum+item.price*item.quantity,0)*(1-this.discount);}};// 用户想“如果这样买”的试算功能functionwhatIfAddItem(cart,newItem){consthypotheticalCart=deepClone(cart);hypotheticalCart.items.push(newItem);returnhypotheticalCart.getTotal();}// 真实的购物车不受影响console.log(shoppingCart.items.length);// 还是2个...或Object.assign)structuredClone()或Lodash记住,在JavaScript的世界里,“拷贝”不是简单的复制粘贴,而是关于“独立性”的哲学选择。选择正确的拷贝方式,能让你的代码更健壮、更可预测!
下次当你面对需要拷贝的场景时,不妨先想想:这是一个需要独立门户的深拷贝,还是一个可以共享芯子的浅拷贝?
✨小测验:你能看出下面代码的输出吗?
constobj={a:1,b:{c:2}};constshallow={...obj};constdeep=JSON.parse(JSON.stringify(obj));shallow.b.c=999;deep.b.c=888;console.log(obj.b.c);// 是多少?答案:999,因为浅拷贝共享了嵌套对象!