avatar

对javaScript的深拷贝和浅拷贝的理解

在讨论深拷贝和浅拷贝之前,我们先来了解一下ECMAScript 的数据类型

ECMAScript 的数据类型

基本数据类型:

undefined,boolean,number,string,null
基本数据类型存放在栈中,数据大小确定,内存空间大小可以分配,是直接按值存放的,所以可以直接访问。

引用类型:

引用类型(object)是存放在堆内存中的,变量实际上是一个存放在栈内存的指针,这个指针指向堆内存中的地址。每个空间大小不一样,要根据情况开进行特定的分配。

深拷贝和浅拷贝的区别

浅拷贝:

  • 只复制一层对象的属性,并不包括对象里面的为引用类型的数据;
  • 增加了一个指针指向已存在的内存地址

深拷贝:

  • 对对象以及对象的所有子对象进行拷贝。
  • 增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存。
  • 使用深拷贝的情况下,释放内存的时候不会因为出现浅拷贝时释放同一个内存的错误。

实现浅拷贝的方式:

  • Object.assign(target, …sources)

    1
    2
    3
    4
    5
    6
    let a = {
    name: 'join'
    }
    let b = Object.assign({}, a)
    a.name = 'jack'
    console.log(b.name) // join
  • 扩展运算符 …

    1
    2
    3
    4
    5
    6
    let a = {
    name: 'join'
    }
    let b = Object.assign(···a)
    a.name = 'jack'
    console.log(b.name) // join
  • 遍历+hasOwnProperty()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function shallowCopy(object) {
    // 遍历 object,并且判断是 object 的属性才拷贝
    for (let key in object) {
    if (object.hasOwnProperty(key)) {
    newObject[key] = object[key];
    }
    }

    return newObject;
    }

实现深拷贝的方式:

  • JSON.parse(JSON.stringify(object))

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    let obj1 = {
    'name' : 'zhangsan',
    'age' : '18',
    'language' : [1,[2,3],[4,5]],
    };
    let obj2 = JSON.parse(JSON.stringify(obj1))

    obj1.language[2] = [7,8]
    console.log(obj1)
    // {
    // 'name' : 'zhangsan',
    // 'age' : '18',
    // 'language' : [1,[2,3],[7,8]],
    //}
    console.log(obj2)
    // {
    // 'name' : 'zhangsan',
    // 'age' : '18',
    // 'language' : [1,[2,3],[5,6]],
    //}
  • 递归+hasOwnProperty()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    let obj1 = {
    name: "zhangsan",
    age: "18",
    language: [1, [2, 3], [4, 5]],
    };
    function deepCopy(object) {
    if (!object || typeof object !== "object") return;

    let newObject = Array.isArray(object) ? [] : {};

    for (let key in object) {
    if (object.hasOwnProperty(key)) {

    newObject[key] =
    typeof object[key] === "object"
    ? deepCopy(object[key])
    : object[key];
    }
    }

    return newObject;
    }
    let obj2 = deepCopy(obj1)
    obj1.language[2] = [7,8]
    console.log(obj1)
    // obj1 = {
    // name: "zhangsan",
    // age: "18",
    // language: [1, [2, 3], [7, 8]],
    // };
    console.log(obj2)
    // obj2 = {
    // name: "zhangsan",
    // age: "18",
    // language: [1, [2, 3], [4, 5]],
    // };
文章作者: Darkerbin
文章链接: https://darkerbin.github.io/2020/04/15/对javaScript的深拷贝和浅拷贝的理解/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 解忧杂货店小店员
打赏
  • 微信
    微信
  • 支付寶
    支付寶