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

对象的浅复制和深度克隆

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

浅复制

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

  1. var obj = { a:1, arr: [2,3] };
  2. var shallowObj = shallowCopy(obj);
  3. function shallowCopy(src) {
  4. var dst = {};
  5. for (var prop in src) {
  6. if (src.hasOwnProperty(prop)) {
  7. dst[prop] = src[prop];
  8. }
  9. }
  10. return dst;
  11. }

深度拷贝的实现

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

  1. var obj = {
  2. a:1,
  3. arr: [2,3],
  4. obj:{
  5. a:1,
  6. b:1
  7. }
  8. };
  9. var copyObj = deepCopy(obj);
  10. function deepCopy(p, c) {
  11.     var c = c || {};
  12.     for (var i in p) {
  13.       if (typeof p[i] === 'object') {
  14.         c[i] = (p[i].constructor === Array) ? [] : {};
  15.         deepCopy(p[i], c[i]);
  16.       } else {
  17.          c[i] = p[i];
  18.       }
  19.     }
  20.     return c;
  21.   }

使用es6 Object.assign(浅复制)

语法:

  1. var merge = Object.assign({}, obj1, obj2 ...);
  2. //该方法不会复制不可枚举形和原型上的数据
  3. //这个是developer.mozilla.org/的例子
  4. const object1 = {
  5. a: 1,
  6. b: 2,
  7. c: 3
  8. };
  9. const object2 = Object.assign({c: 4, d: 5}, object1);
  10. console.log(object2.c, object2.d);
  11. // expected output: 3 5

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

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

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

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

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

  1. deepCopy(obj){
  2. if(obj instanceof Date){
  3. var newObj= obj;
  4. }else{
  5. var newObj= obj instanceof Array?[]:{};
  6. for(var i in obj){
  7. newObj[i]=typeof obj[i]=='object'?deepCopy(obj[i]):obj[i];
  8. }
  9. }
  10. return newObj;
  11. }