【JavaScript 学习--12】JavaScript之深拷贝和浅拷贝

JavaScript拷贝简述

JavaScript里经常用到 copy,而copy又分深拷贝和 浅拷贝。

shallow copy就是让obj1 直接等于oldObj就可以,但是这样会有个问题,就是当你修改任何一个object的时候,都会对另外一个造成同样的修改,所以一般这种copy必须非常小心。
比如下面操作:
在这里插入图片描述

Deep copy就是当你copy之后,修改其中任何一个不会影响另外一个object。

而我们经常在代码实现的时候,常常用到的是深拷贝复杂对象,即拷贝后的对象和原对象是独立开来的,彼此之间的改动不会有影响。

深拷贝之JSON.parse

该方法有个缺点:源对象必须是可以json格式化的。

Deep Copy
//method1  --->Json string化--->
function deepCopy(obj/*: Object*/)/*: Object*/ {
    return JSON.parse(JSON.stringify(obj));
}

深拷贝之lodash库

该方法缺点:需要额外引入第三方库

//method2 ---> lodash 的 _.cloneDeep(value) -->改方法缺点:需要额外引入第三方库
var objects = [{ 'a': 1 }, { 'b': 2 }];
var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
// => false

深拷贝之自己封装

按照自己的方法写个深拷贝,这样就可以不用引入第三方库了。

function deepCopy(obj) {
    var isObject = function(value) {
        var type = typeof value;
        return value !== null && (type === 'object' || type === 'function');
      }
    
    if (obj == null || !isObject(obj)) { //不是对象拷贝,直接返回
        return obj;
    }

    let result = Array.isArray(obj) ? [] : {};
    for(let key in obj) {
        if (obj.hasOwnProperty(key)) { //不拷贝原型链上的对象
            if (isObject(obj[key])) { //嵌套对象,递归调用
                result[key] = deepCopy(obj[key]);
            } else {
                result[key] = obj[key];
            }
        }
    }
    return result;
}

深拷贝之通用方法

//--->更好的通用方式
module.exports = {                                    
     deepCopyIfNeeded,                                                                                                                                                                           
     deepCopy
 };   
      
function deepCopyIfNeeded(resource/*obj|array*/, returnSafeRef/*Boolean,default=false*/)/*obj|array*/ {
     if (returnSafeRef !== undefined && 
         typeof returnSafeRef !== 'boolean') {
         throw new Error(`paras:returnSafeRef can be ignored, otherwise, ` + 
             `must be boolean value\(true, false\)!` + 
             `\nYour secArg is: ${returnSafeRef}`);
     } else if (!returnSafeRef) {
         return resource;
     }
      
     return deepCopy(resource);
 }    
      
function deepCopy(obj) {
    var isObject = function(value) {
        var type = typeof value;
        return value !== null && (type === 'object' || type === 'function');
      }
    
    if (obj == null || !isObject(obj)) { //不是对象拷贝,直接返回
        return obj;
    }

    let result = Array.isArray(obj) ? [] : {};
    for(let key in obj) {
        if (obj.hasOwnProperty(key)) { //不拷贝原型链上的对象
            if (isObject(obj[key])) { //嵌套对象,递归调用
                result[key] = deepCopy(obj[key]);
            } else {
                result[key] = obj[key];
            }
        }
    }
    return result;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木瓜~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值