美文网首页
JavaScript基础知识之深拷贝与浅拷贝

JavaScript基础知识之深拷贝与浅拷贝

作者: 9月的甜橙子 | 来源:发表于2021-08-26 09:02 被阅读0次

    基础

    ECMAScript数据类型

    可以分为两类:基本类型值 和 引用类型值

    • 基本类型值: 那些保存在栈内存中的简单数据段; 即这些值完全保存在内存中的一个位置。
    • 引用类型值: 那些保存在堆内存中的对象;也就是说变量中保存的实际上是一个指针,这个指针指向内存中的另一个位置(保存对象)。


      值存储方式

    基本类型赋值等于在一个新的地方安装连锁店的规范标准新开一个分店,新开的店与其他旧店互不相关,各自运营;而引用类型赋值相当于一个店有两把钥匙,交给两个老板同时管理,两个老板的行为都有可能对一间店的运营造成影响。

    常见的基本数据类型:String、Number、BigInt、Boolean、Null、Undefined、Symbol
    常见的引用数据类型:Object、 Array、Function

    //基本类型值
    let num1 = 1, num2 = num1;
    console.log(num1) //1
    console.log(num2) //1
    num2 = 2; //修改num2
    console.log(num1) //1
    console.log(num2) //2
    //引用类型值
    let obj1 = {x: 1, y: 2}, obj2 = obj1;
    console.log(obj1) //{x: 1, y: 2}
    console.log(obj2) //{x: 1, y: 2}
    obj2.x = 2; //修改obj2.x
    console.log(obj1) //{x: 2, y: 2}
    console.log(obj2) //{x: 2, y: 2}
    

    深拷贝与浅拷贝

    深拷贝 与 浅拷贝的概念只存在于 引用类型。

    • 浅拷贝:只能实现一维对象的复制;当对象是多维时(例如:二维数组或对象),改变二维数组的值会影响原数组【因为二维数组值复制的是其引用】。
    • 深拷贝:可以实现多维对象的复制。

    进阶

    • 简单的一维层次的拷贝可以利用数组自身方法 slice、concat、Array.from()和对象的Object.assign实现,在二维层次上方法失效,无法实现深拷贝
    • JSON.parse(JSON.stringify(obj))可实现二维对象的深拷贝,但对于属性的某些特殊类型的值失效。不能深拷贝有 undefined、function、symbol值的对象,具体来说是因为:在序列化过程中会被忽略(出现在非数组对象的属性值中时)或者被转换成 null(出现在数组中时)。
    • 终极方法,用递归实现引用类型的深拷贝
    function deepCopy(obj) {
       // 创建一个新对象
       let result = {}
       let keys = Object.keys(obj),
           key = null,
           temp = null;
       for (let i = 0; i < keys.length; i++) {
           key = keys[i];    
           temp = obj[key];
           // 如果字段的值也是一个对象则递归操作
           if (temp && typeof temp === 'object') {
               result[key] = deepCopy(temp);
           } else {
           // 否则直接赋值给新对象
               result[key] = temp;
           }
       }
       return result;
    }
    var obj1 = {
       x: {
           m: 1
       },
       y: undefined,
       z: function add(z1, z2) {
           return z1 + z2
       },
       a: Symbol("foo")
    };
    var obj2 = deepCopy(obj1);
    obj2.x.m = 2;
    console.log(obj1); //{x: {m: 1}, y: undefined, z: ƒ, a: Symbol(foo)}
    console.log(obj2); //{x: {m: 2}, y: undefined, z: ƒ, a: Symbol(foo)}
    
    • 其他方法,比如使用第三方库内封装的方法

    参考资料

    https://www.cnblogs.com/james23dong/p/9020771.html

    相关文章

      网友评论

          本文标题:JavaScript基础知识之深拷贝与浅拷贝

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