美文网首页前端
JavaScript 深拷贝和浅拷贝

JavaScript 深拷贝和浅拷贝

作者: 暴躁程序员 | 来源:发表于2022-03-24 17:40 被阅读0次

    拷贝的意思就是复制数据,打个比方,原有一个变量 a 的值是引用类型数据,要求新创建的变量 b 的值与 a 的值相同,
    方案一(浅拷贝):让 b 直接共享a 的数据,那么 a 和 b 任何一方修改数据,另一方的数据也会同步变化
    方案二(深拷贝):让 b 创建一个新的空间用来存储和 a 一样的数据,即 将 a 的数据,以递归的方式拷贝到 b 新创建的数据空间中

    注意:

    1. 基础数据类型的值存储于栈中,他不涉及深浅拷贝(全是深拷贝)
    2. 引用类型的地址存储于栈中,指针指向存储于堆中的值,且其他变量的指针可通过赋值的方式指向同一个堆中的值,当堆中的值发生改变时,会造成所有变量的值同步变化

    总结:浅拷贝 --- 拷贝引用类型的地址,深拷贝 --- 拷贝引用类型的值

    浅拷贝

    1. 变量赋值的方式实现 数组和对象 的浅拷贝
    // 数组浅拷贝
    let a = [1, 2, 3, 4, 5];
    let b = a;
    b[0] = 1000; // 改变 b 的时候,同时也会改变 a
    console.log(a); // [ 1000, 2, 3, 4, 5 ]
    
    // 对象浅拷贝
    let c = { name: 1, age: 1 };
    let d = c;
    d.name = 1000; // 改变 d 的时候,同时也会改变 c
    console.log(c); // { name: 1000, age: 1 }
    
    1. Object.assign() 实现 对象 浅拷贝
    // 对象浅拷贝
    let a = { name: 1, age: 1 };
    let b = Object.assign(a, { other: 999 });
    b.name = 1000; // 改变 b 的时候,同时也会改变 a
    console.log(a); // { name: 1000, age: 1, other: 999 }
    
    // 注意:Object.assign的用法,a 写在第一位才是浅拷贝,写成Object.assign({ other: 999 }, a) ,是深拷贝
    let c = Object.assign({ other: 999 }, a);
    c.name = 888; // 改变 c 的时候,a 不会变化
    console.log(a); // { name: 1000, age: 1, other: 999 }
    

    深拷贝

    1. 递归的方式实现 数组和对象 的深拷贝
    // 数组深拷贝
    let a = [1, 2, 3, 4, 5];
    let b = [];
    for (let i = 0; i < a.length; i++) {
      b.push(a[i]);
    }
    b[0] = 1000; // 改变 b 的时候,a 不受影响
    console.log(b); // [ 1000, 2, 3, 4, 5 ]
    console.log(a); // [ 1, 2, 3, 4, 5 ]
    
    // 对象深拷贝
    let c = { name: 1, age: 1 };
    let d = {};
    for (const k in c) {
      if (Object.hasOwnProperty.call(c, k)) {
        d[k] = c[k];
      }
    }
    d.name = 1000; // 改变 d 的时候,c 不受影响
    console.log(c); // { name: 1, age: 1 }
    console.log(d); // { name: 1000, age: 1 }
    
    1. ... 拓展运算符的方式实现 数组和对象 的深拷贝
    // 数组深拷贝
    let a = [1, 2, 3, 4, 5];
    let b = [...a];
    b[0] = 1000; // 改变 b 的时候,a 的值不变
    console.log(a); // [1, 2, 3, 4, 5];
    console.log(b); // [ 1000, 2, 3, 4, 5 ]
    
    // 对象深拷贝
    let c = { name: 1, age: 1 };
    let d = { ...c };
    d.name = 1000; // 改变 d 的时候,c 的值不会变
    console.log(c); // { name: 1, age: 1 }
    console.log(d); // { name: 1000, age: 1
    
    1. 数组的 sliceconcat方法实现 数组 的深拷贝
    // slice 实现 数组深拷贝
    let a = [1, 2, 3, 4, 5];
    let b = a.slice();
    b[0] = 1000; // 改变 b 的时候,a 的值不变
    console.log(a); // [1, 2, 3, 4, 5];
    console.log(b); // [ 1000, 2, 3, 4, 5 ]
    
    // concat 实现 数组深拷贝
    let c = [1, 2, 3, 4, 5];
    let d = a.concat();
    d[0] = 1000; // 改变 b 的时候,a 的值不变
    console.log(c); // [1, 2, 3, 4, 5];
    console.log(d); // [ 1000, 2, 3, 4, 5 ]
    

    相关文章

      网友评论

        本文标题:JavaScript 深拷贝和浅拷贝

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