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
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
// 定义一个深拷贝函数 接收目标target参数 function deepClone(target) { // 定义一个变量 let result; // 如果当前需要深拷贝的是一个对象的话 if (typeof target === 'object') { // 如果是一个数组的话 if (Array.isArray(target)) { result = []; // 将result赋值为一个数组,并且执行遍历 for (let i in target) { // 递归克隆数组中的每一项 result.push(deepClone(target[i])) } // 判断如果当前的值是null的话;直接赋值为null } else if (target === null) { result = null; // 判断如果当前的值是一个RegExp对象的话,直接赋值 } else if (target.constructor === RegExp) { result = target; } else { // 否则是普通对象,直接for in循环,递归赋值对象的所有值 result = {}; for (let i in target) { result[i] = deepClone(target[i]); } } } else { // 如果不是对象的话,就是基本数据类型,那么直接赋值 result = target; } // 返回最终结果 return result; }

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  105  times

Relevant tags:    JS 

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

Copyright Notice: Freely reproduced for non-commercial use