javaScript中深浅拷贝学习笔记

深浅拷贝的概念:

由于引用类型在栈中只是存储了数据存储的地址,当直接把一个对象赋值给另一个对象时,其实只是把地址复制而已,当其中一个的值改变,另一个也对应改变。这样不是我们想要的结果,故而有了深浅拷贝;
浅复制:只复制一层(即当对象中属性值也为对象时不会进行深层次的复制,只复制一层)。
深复制:会递归复制(即当对象中属性值也为对象时会进行深层次复制,无论多少层)。

js的数据类型:

基本数据类型类型(即直接存储在栈内存中):Undefined、Null、Boolean、Number、String
引用类型(即存储在堆内存中):Object

浅拷贝:

数组的浅拷贝(在js中数组也是一种对象):

1、通过js自带的方法来实现

    var x = [0,1,2,[3,4,[5,6]]];
    var shadow1 = x.slice(0);
    var shadow2 = x.concat();

    console.log(shadow1 === x);  //false  表示内存中存储位置不同(以下相同)
    console.log(shadow2 === x);  //false
    console.log(shadow1[3][2] === x[3][2]);  //true  表示内存中存储位置相同(以下相同)
    console.log(shadow2[3][2] === x[3][2]);  //true

从上面代码可以看出它只实现了一层拷贝,故为浅拷贝
2、自己通过循环来实现浅拷贝

    function shadowCopy(arr) {
        if(typeof arr !== 'object'){
            console.log('your arg is not object');
            return;
        }else{
            var arr0 = [];
                for (var i = 0; i < obj.length; i++) {
                    arr0[i] = arr[i];
                }
        }
        return arr0;
    }
    var shadow = shadowCopy(x);  
    console.log(shadow === x);  //false
    console.log(shadow[3][2] === x[3][2]);  //true

对象的浅拷贝

    var x = {
        a: 1,
        b: 2,
        c: {
            d: 3,
            e: {
                f: 4
            }
        }
    }
    function shadowCopy(obj) {
        if(typeof obj !== 'object'){
            console.log('your arg is not object');
            return;
        }else{
             var obj0 = {};
             for (var i in obj) {
             obj0[i] = obj[i];
             }
        }
        return obj0;
    }
    var shadow = shadowCopy(x);  
    console.log(shadow === x);  //false
    console.log(shadow.c === x.c);  //true

深拷贝

1、通过JSON对象来实现(数组和标准对象都适用)

    var x = [0,1,2,[3,4,[5,6]]];
    var y = {
        a: 1,
        b: 2,
        c: {
            d: 3,
            e: {
                f: 4
            }
        }
    }
    var shadow1 = deepCopyJSON(x);
    var shadow2 = deepCopyJSON(y);

    console.log(shadow1 === x);  //false
    console.log(shadow1[3][2] === x[3][2]);  /false
    console.log(shadow2 === y);  //false
    console.log(shadow2.c.e === y.c.e);  //false

    function deepCopyJSON(obj) {
        if(typeof obj !== 'object'){
            console.log('your arg is not object');
        }else{
            return JSON.parse(JSON.stringify(obj));
        }
    }

2、通过第三方库来实现(详情参阅http://jerryzou.com/posts/dive-into-deep-clone-in-javascript/
3、自己实现(此方法数组和标准对象都适用)

    var x = [0,1,2,[3,4,[5,6]]];
    var y = {
        a: 1,
        b: 2,
        c: {
            d: 3,
            e: {
                f: 4
            }
        }
    }
    var shadow1 = deepCopyMyself(x);
    var shadow2 = deepCopyMyself(y);

    console.log(shadow1 === x);  //false
    console.log(shadow1[3][2] === x[3][2]);  //false
    console.log(shadow2 === y);  //false
    console.log(shadow2.c.e === y.c.e);  //false

    function deepCopyMyself(obj) {
        if(typeof obj !== 'object'){
            console.log('your arg is not object');
            return;
        }else{
            var obj0 = obj.constructor === Array ? [] : {};
            if(obj0.constructor === Object){
                for (var i in obj) {
                    obj0[i] = typeof obj[i] === 'object' ? deepCopyMyself(obj[i]) : obj[i];
                }
            }else{
                for (var i = 0; i < obj.length; i++) {
                    obj0[i] = typeof obj[i] === 'object' ? deepCopyMyself(obj[i]) : obj[i];
                }
            }
        }
        return obj0;
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • underscore 的源码中,有很多地方用到了 Array.prototype.slice() 方法,但是并没有...
    theCoder阅读 610评论 0 1
  • 值类型与引用类型 谈浅拷贝与深拷贝之前,我们需要先理清一个概念,即值类型与引用类型。 什么是值类型与引用类型?这要...
    franose阅读 626评论 1 8
  • 简单讲呢,深浅拷贝,都是进行复制,那么区别主要在于复制出来的新对象和原来的对象是否会互相影响,改一个,另一个也会变...
    _千寻瀑_阅读 255评论 0 2
  • 前言 本文要解决的问题: 为什么会有深拷贝(deep clone)和浅拷贝(shallow clone)的存在 理...
    无亦情阅读 1,885评论 0 5
  • 页面编写心得 先分清项目中的公有逻辑和私有逻辑,把公有逻辑抽离出来。面向对象编程,而不是面向过程编程。 例子1,一...
    涂行知阅读 4,758评论 0 0