hb

浅拷贝深拷贝

d06efztkpin4946213.jpg

关于浅拷贝深拷贝这个问题算是面试常见问题了。

先来说说自己实际中碰到的这个问题。

浅拷贝

        
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
//比如我写了这么一个配置文件 const xjypaths = { 1:{ path_name: '陈列列表页', path: 'exhibitlist', }, 2:{ path_name: '常购页', path: 'category', }, } let obj = xjypaths[1] obj.name="陈列" //那么之后这个xjypaths也就被改了,1对象里就会多一个name的属性,然后就容易在迭代使用里出错。

原因是他们虽然是两个变量,但是引用的变量是同一个变量。看下图分析: 195099820200729092840033542320915.png

那么解决方法就是我们要进行深拷贝,就是要造一个新的变量出来。

深拷贝

方法一

日产用的方法。因为本身开发中不会用到很复杂,所以我也就应用Object.assign(),但Object.assign()只是让对象里第一层的数据没有了关联性,但足够解决大多问题了。

        
  • 1
  • 2
let obj1 = { a: 0 , b: { c: 0}}; let obj2 = Object.assign({}, obj1);

方法二

网上用了JSON.parse(JSON.stringify(obj))

        
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
var function cloneObjectFn (obj){ return JSON.parse(JSON.stringify(obj)) } var obj1={a:2,b{c:0}} var obj2=cloneObjectFn(obj1) console.log(obj2) // {a:2,b{c:0}}

方法三

原生JS实现深拷贝,这个方法主要运用递归,进行深度复制

        
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
//深拷贝 export function deepCopy(data){ var _data; // 初始化结果,因为结果可能为js任意类型,所以没有赋值. // 1. 先验证data是什么类型的数据 // 如果是基本数据类型,那么直接赋值_data if(!(data instanceof Object)){ // 如果是基本数据类型 _data = data // 直接赋值 return _data /// 输出赋值结果,结束下面语句 } if(Array.isArray(data)){ // 验证是不是数组 如果是数组 则进行if语句里面赋值空数组,不是的话直接进行下次判断. _data = [] // 对_data赋值空数组 } // 验证data是否为对象,如果是对象 则进行if语句里面赋值空对象,不是的话直接进行下次判断. if(data.constructor === Object){ _data = {} // 对_data赋值为空对象 } // 2. 将data中内容添加到 _data中 for(var i in data){ // 如果 data[i] 是数组或者对象,则需要进一步深拷贝,所以再次执行deepCopy // 将deepCopy() 的返回值 赋值给_data _data[i] = deepCopy(data[i]) } return _data }

1950998202007290937171571681683094.png

PS. JS中function也是引用类型,但是函数名仅仅是指向该函数的指针,换句话说,一个函数可能会有多个名字

        
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
function sum(num1, num2){ return num1 + num2; } console.log(sum(10, 10));// 20 var anotherSum = sum; // 此时有两个变量sum和anotherSum同时指向该函数(该函数此时有俩名字) console.log(anotherSum(10, 10));// 20 sum = null; // sum置为空后,此时只有anotherSum指向该函数(该函数只有一个名字anotherSum) console.log(anotherSum(10, 10));// 20

如上:代码中首先定义了一个名为sum的函数,用于求两个数的和。然后,又声明了变量anotherSum,赋值为sum,此时anotherSum和sum就指向了同一个函数,因此anotherSum()也正常返回了结果。即使切断sum与函数对象的引用关系,也不会影响anotherSum

---end---

Article at   2021/07/22 18:00  Published  code  Category,viewed  570  times

Relevant tags:    JS 

Address:   https://kedong.me/article/51

Copyright Notice: Freely reproduced for non-commercial use