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

深拷贝-浅拷贝

作者: 枫丶筱 | 来源:发表于2018-08-06 10:40 被阅读8次

    浅拷贝

        var obj = {a: 1, b: {c: 2}}
        var obj1 = obj
        var obj2 = shallowCopy(obj);
        function shallowCopy(src) {
            var dst = {};
             for (var prop in src) {
                 if (src.hasOwnProperty(prop)) {
                     dst[prop] = src[prop];
                  }
              }
             return dst;
        }
        
        var obj3 = Object.assign({}, obj)
        
        obj.a = 2
        obj.b.c = 3
        
        console.log(obj) // {a: 2, b: {c: 3}}
        console.log(obj1) // {a: 2, b: {c: 3}}
        console.log(obj2) // {a: 1, b: {c: 3}}
        console.log(obj3) // {a: 1, b: {c: 3}}
    

    这段代码可以说明赋值得到的对象 obj1 只是将指针改变,其引用的仍然是同一个对象,而浅拷贝得到的的 obj2 则是重新创建了新对象。但是,如果原对象obj中存在另一个对象,则不会对对象做另一次拷贝,而是只复制其变量对象的地址。这是因为浅拷贝只复制一层对象的属性,并不包括对象里面的为引用类型的数据。

    对于数组,更长见的浅拷贝方法便是slice(0)concat()

    ES6 比较常见的浅拷贝方法便是 Object.assign

    深拷贝

    通过上面的这些说明,相信你对深拷贝大致了解了是怎样一个东西了:深拷贝是对对象以及对象的所有子对象进行拷贝。那么如何实现这样一个深拷贝呢?

    1. JSON.parse(JSON.stringify(obj))

    对于常规的对象,我们可以通过JSON.stringify来讲对象转成一个字符串,然后在用JSON.parse来为其分配另一个存储地址,这样可以解决内存地址指向同一个的问题:

        var obj = {a: {b: 1}}
        var copy = JSON.parse(JSON.stringify(obj))
        
        obj.a.b = 2
        console.log(obj) // {a: {b: 2}}
        console.log(copy) // {a: {b: 1}}
    

    但是 JSON.parse()、JSON.stringify也存在一个问题,JSON.parse()和J SON.stringify()能正确处理的对象只有Number、String、Array等能够被 json 表示的数据结构,因此函数这种不能被 json 表示的类型将不能被正确处理。

        var target = {
            a: 1,
            b: 2,
            hello: function() { 
                    console.log("Hello, world!");
            }
        };
        var copy = JSON.parse(JSON.stringify(target));
        console.log(copy);   // {a: 1, b: 2}
        console.log(JSON.stringify(target)); // "{"a":1,"b":2}"
    
    1. 遍历实现属性复制

    既然浅拷贝只能实现非object第一层属性的复制,那么遇到object只需要通过递归实现浅拷贝其中内部的属性即可:

        function extend (source) {
          var target
          if (typeof source === 'object') {
            target = Array.isArray(source) ? [] : {}
            for (var key in source) {
              if (source.hasOwnProperty(key)) {
                if (typeof source[key] !== 'object') {
                  target[key] = source[key]
                } else {
                  target[key] = extend(source[key])
                }
              }
            }
          } else {
            target = source
          }
          return target
        }
        
        var obj1 = {a: {b: 1}}
        var cpObj1 = extend(obj1)
        obj1.a.b = 2
        console.log(cpObj1) // {a: {b: 1}}
        
        var obj2 = [[1]]
        var cpObj2 = extend(obj2) 
        obj2[0][0] = 2
        console.log(cpObj2) // [[1]]

    相关文章

      网友评论

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

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