摘要:中的深拷贝与浅拷贝说到深浅拷贝的时候就不得不说一下中的变量类型了基本类型按值存放在栈内存中的简单数据段可以直接访问引用类型存放在堆内存中的对象变量保存的是一个指向存放数据位置的指针访问引用类型的值时首先从栈中获取到存放该数据位置的指针然后再
JS中的深拷贝与浅拷贝
说到深浅拷贝的时候就不得不说一下JS中的变量类型了:
基本类型: undefined、null、boolean、number、string, 按值存放在栈内存中的简单数据段, 可以直接访问.
引用类型: 存放在堆内存中的对象, 变量保存的是一个指向存放数据位置的指针. 访问引用类型(object, array)的值时, 首先从栈中获取到存放该数据位置的指针, 然后再从堆中取得数据.
__浅拷贝__: 浅拷贝是拷贝引用, 拷贝后的引用都是指向同一个存放数据位置的指针, 无论操作哪一个都是在操作指向在堆中的那一个数据, 所以双方都会有影响.
__深拷贝__: 在堆中重新分配内存, 将源对象的各个属性复制进去. 对拷贝对象和源对象各自操作互不影响.
浅拷贝浅拷贝分两种情况, 拷贝源对象的引用和源对象拷贝实例, 但其属性拷贝引用.
拷贝源的引用
eg:
let obj1 = { a: 1 }; let obj2 = obj1; console.log(obj1 === obj2); // true obj1.a = 2; console.log(obj2.a); // 2
源对象拷贝实例, 其属性对象拷贝引用
外层源对象是拷贝实例, 但是如果源对象的属性元素为复杂数据类型时, 内层元素拷贝引用. 对源对象操作时不影响拷贝对象. 但对其属性操作时, 会改变拷贝对象属性的值. 常用方法: Array.prototype.slice(), Array.prototype.concat(), jQuery的$.extend({}, obj), Object.assign()等. eg:
let obj1 = { a: 1, b: [1, 2, 3], c: { c1: 1 } }; let obj2 = Object.assign({}, obj1); obj2.a = 2; obj2.b[0] = 2; obj2.c.c1 = 10 console.log(obj1); /** 输出结果: { a: 1, b: [2, 2, 3], c: { c1: 10 } } **/
这上面的例子中obj1为源对象, obj2为拷贝对象. 拷贝后修改拷贝对象的属性a没有影响到源对象, 修改拷贝对象的复杂数据类型属性b, c后影响到源对象.
深拷贝深拷贝过后, 源对象、拷贝对象包括其内部元素(包括复杂类型元素)都不互相干扰. 常见方法有JSON.parse(JSON.stringify(obj)), jQuery的$.extend(true, {}, obj), lodash的_.cloneDeep和_clone(value, true). eg:
let obj1 = { a: 1, b: [1, 2, 3], c: { c1: 1 } }; let obj2 = JSON.parse(JSON.stringify(obj1)); obj2.a = 2; obj2.b[0] = 2; obj2.c.c1 = 10 console.log(obj1); /** 输出结果: { a: 1, b: [1, 2, 3], c: { c1: 1 } } **/
最后输出源对象(obj1) 得到结果是源对象未变化.
深拷贝就是增加一个指针(栈内存)申请一个新的堆内存, 并让这个指针指向这个堆内存. 当我们需要复制源对象而又不能修改源对象的时候, 深拷贝就是你想要的.
那么是时候自己实现一个深拷贝方法了:
function deepclone(sObj, cObj) { cObj = cObj || (Array.isArray(sObj) ? [] : {}); for(let i in sObj) { if(typeof sObj[i] === "object") { cObj[i] = Array.isArray(sObj[i]) ? [] : {}; deepclone(sObj[i], cObj[i]) } else { cObj[i] = sObj[i] } }; return cObj; }
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/108253.html
摘要:什么是深拷贝浅拷贝见名知义,无论是深拷贝还是浅拷贝,都是的问题。使用如下以上就是关于中的深拷贝与浅拷贝的知识和如何进行深拷贝的知识了,如果有错或者有其他方式的话,欢迎在下面留言评论啦 前言 最近在写项目的时候涉及到一些父子组件传递个对象或者数组通信啥的,或者是直接复制添加对象啥的,直接使用赋值的时候总会出错。一查原来是浅拷贝的问题,就从网上找了点资料,汇总到这里来了。 1 什么是深拷贝...
摘要:深拷贝和浅拷贝最根本的区别在于是否是真正获取了一个对象的复制实体,而不是引用,深拷贝在计算机中开辟了一块内存地址用于存放复制的对象,而浅拷贝仅仅是指向被复制的内存地址,如果原地址中对象被改变了,那么浅拷贝出来的对象也会相应改变。 深拷贝和浅拷贝最根本的区别在于是否是真正获取了一个对象的复制实体,而不是引用, 深拷贝在计算机中开辟了一块内存地址用于存放复制的对象, 而浅拷贝仅仅是指向被...
摘要:案例中的赋值就是典型的浅拷贝,并且深拷贝与浅拷贝的概念只存在于引用类型。修改修改经测试,也只能实现一维对象的深拷贝。经过验证,我们发现提供的自有方法并不能彻底解决的深拷贝问题。 在说深拷贝与浅拷贝前,我们先看两个简单的案例: //案例1 var num1 = 1, num2 = num1; console.log(num1) //1 console.log(num2) //1 num...
摘要:而引用类型值是指那些保存堆内存中的对象,意思是变量中保存的实际上只是一个指针,这个指针指向内存中的另一个位置,该位置保存对象。而堆内存主要负责对象这种变量类型的存储。我们需要明确一点,深拷贝与浅拷贝的概念只存在于引用类型。 深拷贝和浅拷贝 说起深拷贝和浅拷贝,首先我们来看两个栗子 // 栗子1 var a = 1,b=a; console.log(a); console.log(b) ...
摘要:深拷贝浅拷贝本文主要对深拷贝浅拷贝的解释及实现做一下简单记录。之所以会有深拷贝与浅拷贝之分,是因为不同数据类型的数据在内存中的存储区域不一样。但注意,只能做一层属性的浅拷贝。 深拷贝VS浅拷贝 本文主要对深拷贝&浅拷贝的解释及实现做一下简单记录。原文链接,欢迎star。 之所以会有深拷贝与浅拷贝之分,是因为不同数据类型的数据在内存中的存储区域不一样。 堆和栈是计算机中划分出来用来存储的...
阅读 3511·2021-11-15 11:38
阅读 823·2021-11-08 13:27
阅读 2234·2021-07-29 14:50
阅读 2968·2019-08-29 13:06
阅读 838·2019-08-29 11:22
阅读 2407·2019-08-29 11:04
阅读 3498·2019-08-28 18:23
阅读 889·2019-08-26 13:46