深拷贝与浅拷贝区别,以及深拷贝常用用法

前言

今天在使用Object.assign()方法时候,虽然知道此方法是浅拷贝,但是在以下代码遇到点不理解,于是顺便理了一下深拷贝与浅拷贝。

let target = { a:1, b: 2 };
let source = { b: 3, c: 4 };
const returnedTarget = Object.assign({},target, source);
returnedTarget.a=5
console.log(target);//{ a: 1, b: 2 }
console.log(returnedTarget);//{ a: 5, b: 3, c: 4 }

傻乎乎以为是浅拷贝,以为target的a也会改为5,结果打脸了。

浅拷贝与深拷贝

简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力。

let a=[1,2,3]
let b=a;
b[0]=0;
console.log(a);//[0, 2, 3]
console.log(b);//[0, 2, 3]

=赋值就是典型的浅拷贝,当改变b的值时候,a的值会跟着改变。
这里就牵扯到基本数据类型与复杂数据类型。

基本数据类型与复杂(引用)数据类型

基本数据类型:number,null,undefined,string,boolean,symbol
复杂数据类型:对象({a:1}),数组:([1,2,3]),函数等。
基本类型-名值存储在栈内存中,例如let a=1;


image.png

当b=a时,栈内存会重新开辟一块内存,


image.png

当修改b时候,a不会改变,这是因为a与b存储在不同的内存中,但这不算是深拷贝,因为深拷贝本身只针对较为复杂的object类型数据。
引用类型--名存在栈内存中,值存在于堆内存中,但是栈内存会提供一个引用的地址指向堆内存中的值


image.png

当b=a进行拷贝时,其实复制的是a的引用地址,而并非堆里面的值。


image.png

而当我们a[0]=1时进行数组修改时,由于a与b指向的是同一个地址,所以自然b也受了影响,这就是所谓的浅拷贝了。
image.png

那,要是在堆内存中也开辟一个新的内存专门为b存放值,就像基本类型那样,岂不就达到深拷贝的效果了


image.png

深拷贝方法

1.自己封装一个深拷贝方法

function deepClone(obj){
    let objClone=Array.isArray(obj)?[]:{};
    if(obj&&typeof obj==='object'){
        for(key in obj){
            if(obj.hasOwnProperty(key)){
                    if(obj[key]&&typeof obj[key]==='object'){
                        objClone[key]=deepClone(obj[key])
                    }else{
                      objClone[key]=obj[key]
                    }
            }
        }
    }
    return objClone;
}
let a=[1,2,3];
let b=deepClone(a);
b[0]=4;
console.log(b,a)
//Array [4, 2, 3] Array [1, 2, 3]

此方法原理为拷贝对象各个层级的属性,每一层都拥有独立的栈内存。
2.使用JSON对象的parse和stringify

function deepClone(obj){
    let objString=JSON.stringify(obj);
    let objClone=JSON.parse(objString);
    return objClone;
}
let a=[1,2,3];
let b=deepClone(a);
b[0]=4;
console.log(b,a);
//Array [4, 2, 3] Array [1, 2, 3]

总结

写到这里也基本了解了深拷贝与浅拷贝,也知道为什么要使用深拷贝,以及怎么实现深拷贝,关于JS内存空间的文章,若有兴趣欢迎阅读 JS 从内存空间谈到垃圾回收机制 这篇文章。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,710评论 4 376
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,839评论 2 308
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 112,295评论 0 255
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,776评论 0 223
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,198评论 3 297
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,074评论 1 226
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,200评论 2 322
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,986评论 0 214
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,733评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,877评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,348评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,675评论 3 265
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,393评论 3 246
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,209评论 0 9
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,996评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,212评论 2 287
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 36,003评论 2 280

推荐阅读更多精彩内容