zoukankan      html  css  js  c++  java
  • js深拷贝与浅拷贝

    实现一个页面或者一个功能时,常常遇到的场景需要我们备份一个数组或者对象,这时候出现了深拷贝与浅拷贝效果截然不同呀总结如下:

    浅拷贝:

    1 var
    2     arr = [1, 2, 3, 4],
    3     shallowArr = a;
    4 arr[0] = "change";
    5 console.log(arr);
    6 console.log(shallowArr);

    很简单的例子,很明显结果是两个数组第一项同时发生改变,原因是因为arr与shallowArr两数组为同一数组,仅仅是地址名不同,而地址却是同一个。那么如何避免上面的情况发生呢那就是深拷贝了。

    深拷贝:

    1 var
    2     arr = [1, 2, 3, 4],
    3     deepArr = [].concat(arr);
    4 console.log(arr === shallowArr); // false

    上述代码这是针对数组内部为简单类型的深拷贝,当数组内部的成员为引用类型时上面的方式还能算深拷贝吗?

    1 var
    2     arr = [{ m: 1 }, { n: 2 }],
    3     deepArr = [].concat(arr);
    4 console.log(arr === deepArr); // false
    5 console.log(arr[0] === deepArr[0]); //true

    很明显数组地址发生变化,但是数组内的对象地址并未变化,此时这种拷贝方式就是浅拷贝。

    最实用的深拷贝实现方式:

    1 var
    2     arr = [{ m: 1 }, { n: 2 }],
    3     deepArr = JSON.parse(JSON.stringify(arr));
    4 console.log(arr === deepArr); // false
    5 console.log(arr[0] === deepArr[0]);  //false

    序列化然后反序列化重新生成一个新的数组(引用对象)。

    对象的浅拷贝:

    var 
        obj_a = {
            name: "dqhan",
            age: 25,
            sex: "male",
            hobby: {
                1: "eat",
                2: "play"
            }
        },
        obj_b = obj_a;
    obj_b.age = 18;

     对象的深拷贝:

    var 
        obj_a = {
            name: "dqhan",
            age: 25,
            sex: "male",
            hobby: {
                1: "eat",
                2: "play"
            }
        }
    function deepFunc(argc) {
        var
            newObj = {};
        for (var property in argc) {
            if (typeof argc[property] == "object") newObj[property] = deepFunc(argc[property]);
            else newObj[property] = argc[property];
        }
        return newObj;
    }

     对象与数组均为引用类型,实则原理是一样的。

     总结:

    有没有注意,深拷贝对象都是js中引用类型的对象,基本类型的没有涉及,本质上就是引用类型的对象在堆上分配空间,而深拷贝就是重新给对象在堆上分配一个空间,然后将复制内容到这个新的空间中;而浅拷贝恰恰只是在栈上重新定义了一个指针,指向的位置却依然是原来引用对象的堆空间,改变指的时候当然就都变啦~

  • 相关阅读:
    __type_traits(traits思想)--萃取型别
    traits编程技巧
    SGI空间分配器之第二级配置器剖析
    SGI空间分配器之第一级配置器剖析
    枚举类型与联合类型
    函数指针
    c++中的placement new操作符学习
    第十六章:模板与泛型编程
    第十五章:面向对象编程
    第十五章:面向对象编程
  • 原文地址:https://www.cnblogs.com/moran1992/p/6478706.html
Copyright © 2011-2022 走看看