js对象深拷贝和淺拷贝

深拷贝和浅拷贝之间的差距主要为一点,修改拷贝目标对象的内容是否影响拷贝源对象。

浅拷贝的实现:

源对象和目标对象:

    var target = {},
        data = {
            undefined: undefined,
            empty: null,
            empty_string: '',
            number: 1,
            string: 'test',
            boolean: true,
            object: {
                number: 2
            },
            array: ['a', 'b'],
            fun: function () {
                console.log('test');
            },
            data: data
        };
一、for-in循环
    for (var key in data) {
        target[key] = data[key];
    }

    target.number = 2;
    console.log(data.number);  //1

    target.string = 'copy';
    console.log(data.string);  //test

    target.object.number = 5;  
    console.log(data.object.number); //5

    target.array.push('c');  //["a", "b", "c"]
    console.log(data.array);

    target.fun = function () {
        console.log('copy');  
    }
    data.fun(); //test

二、Object.assign

    target = Object.assign({},data);

    target.number = 2;
    console.log(data.number);  //1

    target.string = 'copy';
    console.log(data.string);  //test

    target.object.number = 5;  
    console.log(data.object.number); //5

    target.array.push('c');  //["a", "b", "c"]
    console.log(data.array);

    target.fun = function () {
        console.log('copy');  
    }
    data.fun(); //test

可以看出target修改对象中的值类型,data中相对应的值未发生变化,但是修改了对象中的引用类型,data中相对象的值发生了变化。这是因为for-in循环和Object.assign仅复制了源对象最外层的属性,对于内层的对象仅复制了一份引用,所以修改了目标对象会影响源对象。

深拷贝实现

一、递归for-in循环
    function deepCopy(tar, resource) {
            for (var key in resource) {
                var source = resource[key];
                if (Object.prototype.toString.call(source) === '[object Object]') {
                    tar[key] = deepCopy(tar[key] || {}, resource[key]);
                } else if(Object.prototype.toString.call(source) === '[object Array]'){
                    tar[key] = deepCopy(tar[key] || [], resource[key]);
                } else if(resource.hasOwnProperty(key)){
                    tar[key] = resource[key];
                }
            }
            return tar;
        }

        target = deepCopy(target, data);

        target.number = 2;
        console.log(data.number); //1

        target.string = 'copy';
        console.log(data.string);  //test

        target.object.number = 5;
        console.log(data.object.number);  //2

        target.array.push('c');
        console.log(data.array);  //["a", "b"]

        target.fun = function () {
            console.log('copy');
        }
        data.fun();
        console.log(target); //test

二、JSON.parse和JSON.stringify

        target = JSON.parse(JSON.stringify(data));

        target.number = 2;
        console.log(data.number);  //1

        target.string = 'copy';
        console.log(data.string);  //test

        target.object.number = 5;
        console.log(data.object.number);  //2

        target.array.push('c');
        console.log(data.array);  //["a", "b"]

可以看出深拷贝不会出现修改目标对象影响源对象的问题,但使用JSON.parse和JSON.stringify方法进行深拷贝将无法拷贝JSON不支持的类型(如function,undefined等)。

over…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值