资讯专栏INFORMATION COLUMN

Javascript中的深复制

Lin_YT / 2144人阅读

摘要:对一个对象或者数组这种引用类型的值进行复制可以分为浅复制和深复制,比如这样的一个对象很明显这个对象是存在两层的,不是基本类型值,而是另一个对象。上面讲的就是浅复制,在实际应用中存在很严重的问题。基于的做法是这样的浅复制深复制

对一个对象或者数组这种引用类型的值进行复制可以分为浅复制和深复制,比如这样的一个对象

let obj={
    a:1,
    b:{
        a:1,
        b:2
    },
    c:3
}

很明显这个对象是存在两层的,obj[b]不是基本类型值,而是另一个对象。如果使用浅复制去拷贝这个对象的话,那么拷贝出来新的对象的b属性的值是原来对象b属性的引用地址,也就是说,如果改变源对象的b属性,新的对象也会受到影响,因为我们只使用浅复制拷贝了一层。

上面讲的就是浅复制,在实际应用中存在很严重的问题。所以我们一般复制对象都是用深复制,深复制不是简单的复制一层,而是遍历整个对象,一直到获取到的值不是引用类型,而是基本类型的时候才进行复制,这样就使得新的对象跟原来的对象完全是两个不同的对象了。

下面是我写的一个简单的深复制函数

let obj={
    a:1,
    b:{
        a:1,
        b:2
    },
    c:3
}

function deepClone(object){
    let obj=new Object();
    if(object instanceof Object){
//         说明是对象
        for(let attr in object){
            if(object.hasOwnProperty(attr)){
//                 过滤基本类型值
                if(typeof object[attr]!="object"||object[attr]==null){
                    obj[attr]=object[attr];
                }else{
                    obj[attr]=deepClone(object[attr]);
                }
            }
        }
    }
    return obj;
}

let obj2=deepClone(obj);
obj.b=1;
console.log(obj,obj2);

注意,这个函数是存在问题的,因为这个函数只能处理纯对象类型,也就是说属性中包含数组的对象该方法是无法处理的。

下面这里有一个方法是stackoverflow上的答案,兼容了数组与对象的

function clone(obj) {
    var copy;

    // Handle the 3 simple types, and null or undefined
    if (null == obj || "object" != typeof obj) return obj;

    // Handle Date
    if (obj instanceof Date) {
        copy = new Date();
        copy.setTime(obj.getTime());
        return copy;
    }

    // Handle Array
    if (obj instanceof Array) {
        copy = [];
        for (var i = 0, len = obj.length; i < len; i++) {
            copy[i] = clone(obj[i]);
        }
        return copy;
    }

    // Handle Object
    if (obj instanceof Object) {
        copy = {};
        for (var attr in obj) {
            if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]);
        }
        return copy;
    }

    throw new Error("Unable to copy obj! Its type isn"t supported.");
}

还有一种比较抖机灵的做法就是

var cloneOfA = JSON.parse(JSON.stringify(a));

这种做法也是可以实现深复制,但是由于JSON.stringify()方法在遇到undefined值时会省略对应的属性,所以这个方法不太推荐使用,存在问题。

基于jQ的做法是这样的

var copiedObject = jQuery.extend({}, originalObject) // shallow copy浅复制

var copiedObject = jQuery.extend(true, {}, originalObject) // deep copy深复制

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/82236.html

相关文章

  • 深入剖析 JavaScript 的深复制

    摘要:的不能算作深复制,但它至少比直接赋值来得深一些,它创建了一个新的对象。它们的主要用途是对存在环的对象进行深复制。比如源对象中的子对象在深复制以后,对应于。希望这篇文章对你们有帮助深复制方法所谓拥抱未来的深复制实现参考资料 本文最初发布于我的个人博客:咀嚼之味 一年前我曾写过一篇 Javascript 中的一种深复制实现,当时写这篇文章的时候还比较稚嫩,有很多地方没有考虑仔细。...

    gclove 评论0 收藏0
  • Javascript的深复制

    摘要:对一个对象或者数组这种引用类型的值进行复制可以分为浅复制和深复制,比如这样的一个对象很明显这个对象是存在两层的,不是基本类型值,而是另一个对象。上面讲的就是浅复制,在实际应用中存在很严重的问题。基于的做法是这样的浅复制深复制 对一个对象或者数组这种引用类型的值进行复制可以分为浅复制和深复制,比如这样的一个对象 let obj={ a:1, b:{ a:1...

    104828720 评论0 收藏0
  • Javascript的深复制

    摘要:对一个对象或者数组这种引用类型的值进行复制可以分为浅复制和深复制,比如这样的一个对象很明显这个对象是存在两层的,不是基本类型值,而是另一个对象。上面讲的就是浅复制,在实际应用中存在很严重的问题。基于的做法是这样的浅复制深复制 对一个对象或者数组这种引用类型的值进行复制可以分为浅复制和深复制,比如这样的一个对象 let obj={ a:1, b:{ a:1...

    AbnerMing 评论0 收藏0
  • 在js的深复制实现方法

    摘要:针对本话题,我在年月发布了新的文章深入剖析的深复制要实现深复制有很多办法,比如最简单的办法有上面这种方法好处是非常简单易用,但是坏处也显而易见,这会抛弃对象的,也就是深复制之后,无论这个对象原本的构造函数是什么,在深复制之后都会变成。 针对本话题,我在2015年5月发布了新的文章:深入剖析 JavaScript 的深复制 要实现深复制有很多办法,比如最简单的办法有: var...

    Alliot 评论0 收藏0

发表评论

0条评论

Lin_YT

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<