重新梳理下js中的深拷贝和浅拷贝
栏目: JavaScript · 发布时间: 5年前
内容简介:1.最简单的浅拷贝就赋值。由于js中的对象都是复杂数据类型,这种数据在内存中存储的时候,存放在堆中。当简单赋值的时候,其实是将该对象的指针指向同一个堆地址。简单的数据类型存放在栈中,当对简单的数据类型进行赋值的时候,其实就是直接在栈中新开辟一个地方专门来存储一样的值。
浅拷贝:
1.最简单的浅拷贝就赋值。
由于js中的对象都是复杂数据类型,这种数据在内存中存储的时候,存放在堆中。当简单赋值的时候,其实是将该对象的指针指向同一个堆地址。
简单的数据类型存放在栈中,当对简单的数据类型进行赋值的时候,其实就是直接在栈中新开辟一个地方专门来存储一样的值。
所谓的浅拷贝就是,后面的对象和前面的对象在第一层数据结构中指向同一个堆地址。但是如果前面的数据不止有一层,如:
let obj = { a: {a: "hello", b: 21} };
此时,使用Object.assign()和...Object方式实现的都是浅拷贝。
此时,第一层数据虽然指向了另一个新的堆地址,但是它内部的子对象的指针却还是同一个地址。这种情况也属于浅拷贝,只不过是比那种直接赋值(直接复制堆地址)的方式要深刻一些。
2.数组和对象的浅拷贝
数组的浅拷贝,有三种方式:
(1) arr1 = arr2; (2) arr2 = arr1.slice(0); (3) arr2 = arr1.concat();
对象的浅拷贝,也有3种方式:
(1) obj2 = obj1; (2) obj2 = Object.assign(obj1 ,{} ) (3) obj2 = {...obj1}
深拷贝
对象的深拷贝实际上就是,将前一个对象复制一份给后面的那个对象,不管前面的那个对象中的数据结构嵌套有多深,当改变其中一个对象中的任意深度的某个值后,另一个对象中的该值不会受任何影响。
1.当对象中的所有属性值都是简单数据类型的时候:
function easyCopy(p) { var c = {}; for (var i in p) { c[i] = p[i]; } c.uber = p; return c; }
2.当要复制的对象中存在某个属性的value值是对象或者数组时:
如果像上面的简单类型那样直接赋值,那么子对象对应的属性实际上指向的是和被拷贝对象中子对象一样的内存地址。因此,只要改了一个,另一个也会跟着改变。
function deepCopy(p, c) { let c = c || {}; for (let i in p) { if(! p.hasOwnProperty(i)){ continue; } if (typeof p[i] === 'object') { c[i] = (p[i].constructor === Array) ? [] : {}; deepCopy(p[i], c[i]); } else { c[i] = p[i]; } } return c; } Parent = {name: 'foo', birthPlaces: ['北京','上海','香港']} var Child = deepCopy(Parent);
总结:
浅拷贝:你变我也变,嵌套对象变,就会跟着变。
深拷贝:管你怎么变,互不影响。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
你不知道的JavaScript(上卷)
[美] Kyle Simpson / 赵望野、梁杰 / 人民邮电出版社 / 2015-4 / 49.00元
JavaScript语言有很多复杂的概念,但却用简单的方式体现出来(比如回调函数),因此,JavaScript开发者无需理解语言内部的原理,就能编写出功能全面的程序;就像收音机一样,你无需理解里面的管子和线圈都是做什么用的,只要会操作收音机上的按键,就可以收听你喜欢的节目。然而,JavaScript的这些复杂精妙的概念才是语言的精髓,即使是经验丰富的JavaScript开发者,如果没有认真学习也无......一起来看看 《你不知道的JavaScript(上卷)》 这本书的介绍吧!