JS 深拷贝和浅拷贝

JS 深拷贝和浅拷贝 面试必考题

看了,就要会,不然都是浪费

一、先来看一下下面代码输出什么?

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

嗯?明明b复制了a,为啥修改数组a,数组b也跟着变了,为什么呢?

课前知识必备( 基本数据与引用数据)

  • 基本数据类型: numberstringbooleannullundefinedsymbol
  • 引用数据类型: Object有常规名值对的无序对象{a:1},数组[1,2,3],以及函数function

二、区别是什么呢? (重点)

基本类型存在栈stack,应用类型存在堆heap

如下图很好解释了堆栈

  • 栈:自动分配内存空间,系统自动释放,里面存放的是基本类型的值和引用类型的地址

  • 堆:动态分配的内存,大小不定,也不会自动释放。里面存放引用类型的值。
    image

简单来说,就是浅拷贝只是复制了stack 的地址(指向同一个object),深拷贝就是开辟了一个新的内存,来编辑数据

三、怎样可以深拷贝

方法一 、JSON 解析

const data = {a:[1,2,3,4],b:"name"}
const deepclone = JSON.parse(JSON.stringify(res)) // 深拷贝

方法二、使用lodash 库

按需引入

<script src="lodash.js"></script>
import clonedeep from 'lodash.clonedeep'
var objects = [{ 'a': 1 }, { 'b': 2 }];
 
var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
// => false

方法三、除了上面两种方法之外,我们还可以借用JQ的extend方法。

$.extend( [deep ], target, object1 [, objectN ] )

deep表示是否深拷贝,为true为深拷贝,为false,则为浅拷贝

target Object类型 目标对象,其他对象的成员属性将被附加到该对象上。

object1 objectN可选。 Object类型 第一个以及第N个被合并的对象。

let a=[0,1,[2,3],4],
    b=$.extend(true,[],a);
a[0]=1;
a[2][0]=1;
console.log(a,b);

方法四、当然还可以自己DIY,写个递归

function deepClone(obj){
    let objClone = Array.isArray(obj)?[]:{};
    if(obj && typeof obj==="object"){
        for(key in obj){
            if(obj.hasOwnProperty(key)){
                //判断ojb子元素是否为对象,如果是,递归复制
                if(obj[key]&&typeof obj[key] ==="object"){
                    objClone[key] = deepClone(obj[key]);
                }else{
                    //如果不是,简单复制
                    objClone[key] = obj[key];
                }
            }
        }
    }
    return objClone;
}    
let a=[1,2,3,4],
    b=deepClone(a);
a[0]=2;
console.log(a,b);

跟之前想象的一样,现在b脱离了a的控制,不再受a影响了。

posted @ 2021-08-26 17:33  Yonah凤娇  阅读(236)  评论(0)    收藏  举报