结合工作经历,浅浅的总结了一下引用类型的深拷贝与浅拷贝。
先说一个大前提:浅拷贝和深拷贝只针对引用类型,基本数据类型不存在深浅拷贝。
一、浅拷贝
浅拷贝:拷贝的是引用地址。
常见方法(浅拷贝比较简单就不举例说明了):
1.拷贝对象
1.1 Object.assgin()
1.2 展开运算符 {...obj}
2.拷贝数组
2.1 Array.prototype.concat()
2.2展开运算符 [...arr]
再强调一下:如果是基本数据类型拷贝值,引用数据类型拷贝的是地址 (简单理解: 如果是单层对象,没问题,如果有多层就有问题)
二、深拷贝
深拷贝:拷贝的是对象,不是地址
常见方法(深拷贝会详细说一下):
1.函数递归实现深拷贝
如果一个函数在内部可以调用其本身,那么这个函数就是递归函数。
- 简单理解:函数内部自己调用自己, 这个函数就是递归函数
- 递归函数的作用和循环效果类似
- 由于递归很容易发生“栈溢出”错误(stack overflow),所以必须要加退出条件 return
<body> <script> const obj = { uname: 'pink', age: 18, hobby: ['乒乓球', '足球'], family: { baby: '小pink' } } const o = {} // 拷贝函数 function deepCopy(newObj, oldObj) { debugger for (let k in oldObj) { // 处理数组的问题 一定先写数组 在写 对象 不能颠倒 if (oldObj[k] instanceof Array) { newObj[k] = [] // newObj[k] 接收 [] hobby // oldObj[k] ['乒乓球', '足球'] deepCopy(newObj[k], oldObj[k]) } else if (oldObj[k] instanceof Object) { newObj[k] = {} deepCopy(newObj[k], oldObj[k]) } else { // k 属性名 uname age oldObj[k] 属性值 18 // newObj[k] === o.uname 给新对象添加属性 newObj[k] = oldObj[k] } } } deepCopy(o, obj) // 函数调用 两个参数 o 新对象 obj 旧对象 console.log(o) o.age = 20 o.hobby[0] = '篮球' o.family.baby = '老pink' console.log(obj) console.log([1, 23] instanceof Object) // 复习 // const obj = { // uname: 'pink', // age: 18, // hobby: ['乒乓球', '足球'] // } // function deepCopy({ }, oldObj) { // // k 属性名 oldObj[k] 属性值 // for (let k in oldObj) { // // 处理数组的问题 k 变量 // newObj[k] = oldObj[k] // // o.uname = 'pink' // // newObj.k = 'pink' // } // } </script> </body>
2.js库lodash里面cloneDeep内部实现了深拷贝
<body> <!-- 先引用 --> <script src="./lodash.min.js"></script> <script> const obj = { uname: 'pink', age: 18, hobby: ['乒乓球', '足球'], family: { baby: '小pink' } } const o = _.cloneDeep(obj) console.log(o) o.family.baby = '老pink' console.log(obj) </script> </body>
3.通过JSON序列化实现深拷贝
<body> <script> const obj = { uname: 'pink', age: 18, hobby: ['乒乓球', '足球'], family: { baby: '小pink' } } // 把对象转换为 JSON 字符串 // console.log(JSON.stringify(obj)) const o = JSON.parse(JSON.stringify(obj)) console.log(o) o.family.baby = '123' console.log(obj) </script> </body>
以上就是对深浅拷贝的总结,在工作中往往用JSON序列化来实现深拷贝,因为这种方法最简单直接。如果对小伙伴们有用,欢迎点赞评论~