美文网首页深究JavaScript
深拷贝与浅拷贝区别,以及深拷贝常用用法

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

作者: 景元合 | 来源:发表于2020-01-03 17:31 被阅读0次

前言

今天在使用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 从内存空间谈到垃圾回收机制 这篇文章。

相关文章

  • js浅拷贝、深拷贝

    前言 本文主要简单讲一下什么是浅拷贝、什么是深拷贝、深拷贝与浅拷贝的区别,以及怎么进行深拷贝和怎么进行浅拷贝。 一...

  • 深拷贝与浅拷贝

    本文将讲述一下几点 深拷贝与浅拷贝的区别。 深拷贝的常用方法 切记。只有引用类型才存在深拷贝与浅拷贝的问题哦~,基...

  • 深拷贝和浅拷贝

    干货!深拷贝和浅拷贝的区别 深拷贝才是拷贝,浅拷贝就是Retain Copy与Retain的区别 Copy: 根据...

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

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

  • iOS--拷贝相关题

    1、什么是深拷贝什么是浅拷贝?浅拷贝和深拷贝的区别 * 浅拷贝(shallow copy):指针拷贝,对于被拷贝对...

  • copy和mutableCopy的区别

    copy和mutableCopy的区别 深拷贝和浅拷贝的区别 在OC中对象的拷贝方式有两种:深拷贝和浅拷贝.浅拷贝...

  • iOS 深浅拷贝

    iOS深拷贝与浅拷贝的区别 深拷贝与浅拷贝的概念:(我的理解,望不吝赐教) 浅拷贝:只copy一份对象的指针,指向...

  • 深拷贝、浅拷贝的理解与使用场景

    什么是深拷贝、浅拷贝? 通俗解释:深拷贝是内容拷贝,浅拷贝是地址拷贝 区别点: 深拷贝会创建一个新的内存空间,拷贝...

  • 深拷贝、浅拷贝

    父类实现深拷贝时,子类如何实现深度拷贝。父类没有实现深拷贝时,子类如何实现深度拷贝。 深拷贝同浅拷贝的区别:浅拷贝...

  • 面试题整理

    父类实现深拷贝时,子类如何实现深度拷贝。父类没有实现深拷贝时,子类如何实现深度拷贝。 深拷贝同浅拷贝的区别:浅拷贝...

网友评论

    本文标题:深拷贝与浅拷贝区别,以及深拷贝常用用法

    本文链接:https://www.haomeiwen.com/subject/gdttactx.html