美文网首页
JS 中关于浅拷贝和深拷贝的理解

JS 中关于浅拷贝和深拷贝的理解

作者: 前端_Fn | 来源:发表于2020-05-31 20:32 被阅读0次

如何区分深拷贝和浅拷贝?

假设 B 复制了 A ,当 A 修改时,看 B 是否跟着发生改变

  • 如果 B 改变了,说明是浅拷贝。
  • 如果 B 没改变,说明时深拷贝。

首先,简单阐述栈堆,基本数据类型与引用数据类型。
因为这些概念能更好的让我们理解浅拷贝和深拷贝。

我们来举例浅拷贝的例子:

let obj = {
    name: "张三",
    habby: {
        one: "旅行",
        two: "摸鱼"
    }
};
let newObj = {
    ...obj
};
newObj.habby.one = "打代码";  // 修改
console.log(obj); // 打印如下 
微信截图_20200531000200.png

我明明 newObj 复制了 obj,为什么修改了 newObj ,obj 也跟着改变。那么这里,就得引入基本数据类型与引用数据类型的概念了。

基本数据类型有哪些?

number、string、undefined、null、symbol、boolean。


引用数据类型

array、object、function


基本数据类型:名值存储在栈内存中。

微信截图_20200531000200.png

比如 let a = 1,当 b = a 复制时,栈内存会新开辟一个内存,例如这样:

2.png

所以当你修改 a = 2,对 b 并不会造成影响。当然,let a = 1,b = a。虽然 b 不受影响,但这也不算是深拷贝,因为深拷贝本身只针对较为复杂的 object 类型数据。


引用数据类型:名存在栈内存中,值存在于堆内存中。但是栈内存会提供一个引用的地址指向堆内存中的值。

3.png

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

4.png

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

6.png

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

7.png

方法一:通过递归去复制所有的层级属性实现深拷贝效果

function deepCopy(obj){
    let newObj = Array.isArray(obj) ? [] : {};
    for(let key in obj){
        if(obj.hasOwnProperty(key)){
            if(typeof obj[key] === "object"){
                newObj[key] = deepCopy(obj[key]);
            } else {
                newObj[key] = obj[key];
            }
        }
    };
    return newObj;
};
let obj = {
    name: "张三",
    habby: {
        one: "旅行",
        two: "摸鱼"
    }
};
let newObj = deepCopy(obj);
newObj.habby.one = '排球';
console.log(obj)
8.png

可以看到现在 obj 脱离了 newObj 的控制,不再受 newObj 的影响了。

方法二:通过 JSON 对象的 parse 和 stringify,缺点是对 function 和 undefined 无效。

let obj = {
    name: "张三",
    habby: {
        one: "旅行",
        two: "摸鱼"
    }
};
let newObj = JSON.parse(JSON.stringify(obj));
newObj.habby.one = '排球';
console.log(obj);
9.png

可以看到 obj 不受 newObj 的控制了。

可以使用 localStorage实现对象数组存储,不过这里不多说,不太推荐。

最后,深拷贝能帮你更安全安心的去操作数据,根据实际情况来使用深拷贝。

相关文章

  • JS中的深拷贝与浅拷贝

    知乎:js中的深拷贝和浅拷贝? 掘金: js 深拷贝 vs 浅拷贝 前言 首先深拷贝与浅拷贝只针对 Object,...

  • 浅拷贝和深拷贝

    本文参考:JavaScript中的浅拷贝和深拷贝js 深拷贝 vs 浅拷贝深入剖析 JavaScript 的深复制...

  • JS实现深拷贝、instanceof、判断是否为数组

    JS深拷贝 JS中拷贝对象可以按照拷贝的程度可以分为浅拷贝和深拷贝,有些时候我们需要拷贝之后的对象和拷贝之前的对象...

  • JS中对象的复制

    JS中的对象复制分为两种情况:深拷贝和浅拷贝。深拷贝和浅拷贝的区别在于对数组和对象的拷贝,对它们拷贝时浅拷贝只是拷...

  • iOS面试题-第二页

    11.深拷贝和浅拷贝的理解. 深拷贝;拷贝的内容. 浅拷贝:拷贝的指针. 深拷贝如: NSMutableDicti...

  • js浅拷贝深拷贝

    js浅拷贝,深拷贝的简单实现 基础数据 浅拷贝 深拷贝

  • JS 中关于浅拷贝和深拷贝的理解

    如何区分深拷贝和浅拷贝? 假设 B 复制了 A ,当 A 修改时,看 B 是否跟着发生改变 如果 B 改变了,说明...

  • 实现一个深拷贝

    深拷贝和浅拷贝是针对复杂数据类型来说的,浅拷贝只拷贝一层,而深拷贝是层层拷贝。 代码中理解...

  • js的深拷贝与浅拷贝及实现方法

    前提 理解深拷贝和浅拷贝之前,我们先理解下js变量的存储方式。 js变量分为基础类型(Undefined、Null...

  • Objective-C中的浅拷贝和深拷贝

    Objective-C中的浅拷贝和深拷贝 Objective-C中的浅拷贝和深拷贝

网友评论

      本文标题:JS 中关于浅拷贝和深拷贝的理解

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