美文网首页
深拷贝&浅拷贝

深拷贝&浅拷贝

作者: 尤樊容 | 来源:发表于2017-07-19 16:08 被阅读16次

数据保存到对象以后会涉及到拷贝的问题,而数据保存的格式多样,这就涉及到了深拷贝和浅拷贝的问题。
产生的原因:

    var arr1 = [1,2,3,4,5];
    var arr2 = arr1;
    arr2[1] = 6;
    document.write("arr1: " + arr1 + "<br/>");  //打印结果:arr1: 1,6,3,4,5
    document.write("arr2: " + arr2);//打印结果:arr2: 1,6,3,4,5

    //打印结果:
    //arr1: 1,6,3,4,5
    //\arr2: 1,6,3,4,5

用以上方式将数组拷贝到arr2中是直接让两个对象同时指向同一片内存区域,更改其中的一个,另一个也会更改,为了使两个对象保存以后不会互相影响,用下面的一个简单地例子说明:

    var arr1 = [1,2,3,4,5];
    var arr2 = [];
    for(var i = 0; i < arr1.length; i++){
        arr2[i] = arr1[i];
    }
    arr2[1] = 6;
    document.write("arr1: " + arr1 + "<br/>");
    document.write("arr2: " + arr2);
    
    //打印结果:
    //arr1: 1,2,3,4,5
    //arr2: 1,6,3,4,5

使用循环将arr1里面的数据一一添加到新的对象中,这样打印出来的结果就不会相互影响,也就是一个浅拷贝。
Array的slice函数也可以实现浅拷贝:

    //此方法只针对Array
    var arr1 = [1,2,3,4,5];
    var arr2 = arr1.slice(1);
    arr2[0] = "a";
    document.write(arr1 + "<br/>");
    document.write(arr2);

    //输出结果:
    //1,2,3,4,5
    //a,3,4,5

但是这个方法也只是浅拷贝的一种,数组有多层的时候也是不行的,例如:

    var arr1 = [[1,11],[2,22],[3,33]];
    var arr2 = arr1.slice(1);
    arr2[0][1] = "a";
    document.write(arr1 + "<br/>");
    document.write(arr2);

    //输出结果:
    //1,11,2,a,3,33
    //2,a,3,33

Array的concat函数也是浅拷贝,实例如下:

    var arr1 = [1,2,3];
    var arr2 = [4,5,6];
    var arr3 = arr1.concat(arr2);
    arr2[1] = "aa";
    document.write(arr3);

    //输出结果:
    //1,2,3,4,5,6

生成的第三个数组是独立的,受arr1和arr2影响。但也只能实现浅拷贝。

浅拷贝只是拷贝了对象最外面的一层,但是并不是所有的对象都是简单到只有一层,所以出现了深拷贝,利用递归将对象深拷贝。
用递归写了一个例子:

var object1 = [1,2,3,4,{a:"aaa", b:"bbb"},6,7,[8,9,{c:"ccc", d:"ddd"}]];
function deepCopy(obj, newObj) {
    var newObj = newObj || ((obj.constructor === Array) ? [] : {});
    for (var i in obj) {
        if (typeof obj[i] === 'object') {
            newObj[i] = (obj[i].constructor === Array) ? [] : {};
            deepCopy(obj[i], newObj[i]);
        } else {
            newObj[i] = obj[i];
        }
    }
    return newObj;
}
var arr = deepCopy(object1);
arr[4].a = "ccc";
console.log(object1);// [1,2,3,4,{a:"aaa", b:"bbb"},6,7,[8,9,{c:"ccc", d:"ddd"}]]
console.log(arr);// [1,2,3,4,{a:"ccc", b:"bbb"},6,7,[8,9,{c:"ccc", d:"ddd"}]]

在拷贝的时候检查数据的格式,然后分情况拷贝。这样的方法可以提高代码的重用,在数据格式未知的情况下,避免出错,但是这样写在某些情况下也会降低代码执行的效率,比如数据已知并且单一的情况下,浅拷贝就可以满足,并且可以提高代码执行的效率。

相关文章

  • iOS深拷贝(MutableCopy)与浅拷贝(Copy)的区别

    深拷贝和浅拷贝的概念 iOS中有深拷贝和浅拷贝的概念,那么何为深拷贝何为浅拷贝呢?浅拷贝:浅拷贝并不拷贝对象本身,...

  • 深拷贝 & 浅拷贝

    浅拷贝:大多数对象都引用(指向)其他对象,不复制引用对象。新复制的对象只指向现有的引用对象。 例如 NSArray...

  • 深拷贝&浅拷贝

    数据保存到对象以后会涉及到拷贝的问题,而数据保存的格式多样,这就涉及到了深拷贝和浅拷贝的问题。产生的原因: 用以上...

  • 浅拷贝&深拷贝

  • iOS - copy 与 mutableCopy

    一说到拷贝,就不得不提浅拷贝和深拷贝。 何谓浅拷贝?何谓深拷贝? 往简单的说: 浅拷贝:拷贝地址。 深拷贝:拷贝内...

  • iOS面试题-第二页

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

  • js浅拷贝深拷贝

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

  • JS中的深拷贝与浅拷贝

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

  • iOS--拷贝相关题

    1、什么是深拷贝什么是浅拷贝?浅拷贝和深拷贝的区别 * 浅拷贝(shallow copy):指针拷贝,对于被拷贝对...

  • 2018-10-10day9函数基础

    1.浅拷贝、深拷贝 copy.copy(对象):浅拷贝copy.deepcopy(对象):深拷贝""" """拷贝...

网友评论

      本文标题:深拷贝&浅拷贝

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