javascript: 复制对象时的深拷贝及浅拷贝(chrome 105.0.5195.125)
一,js代码
<html> <head> <meta charset="utf-8"/> <title>测试</title> </head> <body> <button onclick="assign()">无效:变量直接赋值</button><br/><br/><br/> <button onclick="assignCopy()">浅拷贝:assign复制对象</button><br/><br/> <button onclick="operatorCopy()">浅拷贝:对象展开运算符复制对象</button><br/><br/><br/> <button onclick="eachCopy()">深拷贝:遍历属性复制对象</button><br/><br/> <button onclick="jsonCopy()">深拷贝:json复制对象</button><br/><br/> <script> //直接赋值复制对象 function assign() { let obj1 = {name:'老刘',age:30,info:{address:'hebei',mobile:'13888888888'}} let obj2 = obj1; console.log('obj1:'); console.log(obj1); console.log('obj2:'); console.log(obj2); obj1.name = '老王测试'; obj1.info.mobile = '13899999999'; console.log('obj1:'); console.log(obj1); console.log('obj2:'); console.log(obj2); console.log('是否同一个对象:'); console.log(obj1 === obj2 ); } //Object.assign复制对象 function assignCopy() { let obj1 = {name:'老刘',age:30,info:{address:'hebei',mobile:'13888888888'}} var obj2 = Object.assign({}, obj1); console.log('obj1:'); console.log(obj1); console.log('obj2:'); console.log(obj2); obj1.name = '老王测试'; obj1.info.mobile = '13899999999'; console.log('obj1:'); console.log(obj1); console.log('obj2:'); console.log(obj2); console.log('是否同一个对象:'); console.log(obj1 === obj2 ); } //对象展开运算符复制对象 function operatorCopy() { let obj1 = {name:'老刘',age:30,info:{address:'hebei',mobile:'13888888888'}} let obj2 = {...obj1}; console.log('obj1:'); console.log(obj1); console.log('obj2:'); console.log(obj2); obj1.name = '老王测试'; obj1.info.mobile = '13899999999'; console.log('obj1:'); console.log(obj1); console.log('obj2:'); console.log(obj2); console.log('是否同一个对象:'); console.log(obj1 === obj2 ); } //用json的属性复制对象 function jsonCopy() { let obj1 = {name:'老刘',age:30,info:{address:'hebei',mobile:'13888888888'}} let obj2 = JSON.parse(JSON.stringify(obj1)); console.log('obj1:'); console.log(obj1); console.log('obj2:'); console.log(obj2); obj1.name = '老王测试'; obj1.info.mobile = '13899999999'; console.log('obj1:'); console.log(obj1); console.log('obj2:'); console.log(obj2); console.log('是否同一个对象:'); console.log(obj1 === obj2 ); } //遍历属性复制对象 function eachCopy() { let obj1 = {name:'老刘',age:30,info:{address:'hebei',mobile:'13888888888'}} let obj2 = deepClone(obj1); console.log('obj1:'); console.log(obj1); console.log('obj2:'); console.log(obj2); obj1.name = '老王测试'; obj1.info.mobile = '13899999999'; console.log('obj1:'); console.log(obj1); console.log('obj2:'); console.log(obj2); console.log('是否同一个对象:'); console.log(obj1 === obj2 ); } //函数,遍历对象的属性复制 function deepClone(obj) { if(obj === null) return null if(typeof obj !== 'object') return obj; var newObj = new obj.constructor (); //保持继承链 for (var key in obj) { if (obj.hasOwnProperty(key)) { //不遍历其原型链上的属性 var val = obj[key]; newObj[key] = typeof val === 'object' ? arguments.callee(val) : val; // 使用arguments.callee解除与函数名的耦合 } } return newObj; } </script> </body> </html>
说明:刘宏缔的架构森林是一个专注架构的博客,
网站:https://blog.imgtouch.com
本文: https://blog.imgtouch.com/index.php/2023/06/03/javascript-fu-zhi-dui-xiang-shi-de-shen-kao-bei-ji-qian-kao/
对应的源码可以访问这里获取: https://github.com/liuhongdi/
或: https://gitee.com/liuhongdi
说明:作者:刘宏缔 邮箱: 371125307@qq.com
二,测试效果:
无效:直接赋值时:obj1、obj2是同一个对象:
浅拷贝:对象中嵌套的对象没有成功复制:
深拷贝:对象中嵌套的对象也被成功复制为新对象:
三,查看chrome的版本: