当前位置:首页 > 对象的浅复制和深度克隆

对象的浅复制和深度克隆

发布于 2018-04-27 阅读 367 次 Javascript

浅复制

只会复制第一层,对于引用类型数据,因为只是简单的赋值,还是引用的相同地址,所有改变原来的数据会引起拷贝后的数据。

var obj = { a:1, arr: [2,3] };
var shallowObj = shallowCopy(obj);

function shallowCopy(src) {
  var dst = {};
  for (var prop in src) {
    if (src.hasOwnProperty(prop)) {
      dst[prop] = src[prop];
    }
  }
  return dst;
}

深度拷贝的实现

递归进行拷贝,遇到引用类型就递归拷贝,不会出现浅拷贝的问题。

var obj = {
    a:1,
    arr: [2,3],
    obj:{
        a:1,
        b:1
    }
};

var copyObj = deepCopy(obj);

function deepCopy(p, c) {
    var c = c || {};
    for (var i in p) {
      if (typeof p[i] === 'object') {
        c[i] = (p[i].constructor === Array) ? [] : {};
        deepCopy(p[i], c[i]);
      } else {
         c[i] = p[i];
      }
    }
    return c;
  }

使用es6 Object.assign(浅复制)

语法:

var merge = Object.assign({}, obj1, obj2 ...);
//该方法不会复制不可枚举形和原型上的数据

//这个是developer.mozilla.org/的例子
const object1 = {
  a: 1,
  b: 2,
  c: 3
};

const object2 = Object.assign({c: 4, d: 5}, object1);

console.log(object2.c, object2.d);
// expected output: 3 5

详细的文档,可以使劲点击下面的链接,需要翻墙(虽然英文解释看不懂,但是我们可以读代码呀)。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

突然想到,这样也阔以(只适用于字面量形式)

看来自己还得时常巴拉下自己写的代码,不然别说看别人的,看自己的代码都跟读天数一样啊

    function clone (json) {
      var txt=JSON.stringify(json);
      return JSON.parse(txt);
    }

deepCopy缺点:不能实现包装类型比如通过new String()或者new Number()创建的对象 Date对象的深度克隆
对于Date对象就直接赋值就好,下面给出一个修改例子:

deepCopy(obj){
    if(obj instanceof Date){
        var newObj= obj; 
    }else{
        var newObj= obj instanceof Array?[]:{};
        for(var i in obj){
            newObj[i]=typeof obj[i]=='object'?deepCopy(obj[i]):obj[i];
        }
    }
    return newObj;
}