对象的深拷贝和浅拷贝

2017-06-21  本文已影响0人  颠倒的黑白

数组的深浅拷贝

在使用JavaScript对数组进行操作的时候,我们经常需要将数组进行备份,事实证明如果只是简单的将它赋予其他变量,那么我们只要更改其中的任何一个,然后其他的也会跟着改变,这就导致了问题的发生。

浅拷贝
var arr = ["One","Two","Three"];
console.log(arr);//["One", "Two", "Three"]

var arrto = arr;
arrto[1] = "test";
console.log("数组的原始值:" + arr + "<br />");//Export:数组的原始值:One,test,Three
console.log("数组的新值:" + arrto + "<br />");//Export:数组的新值:One,test,Three

像上面的这种直接赋值的方式就是浅拷贝,很多时候,这样并不是我们想要得到的结果,其实我们想要的是arr的值不变,不是吗?

深拷贝

方法一:js的slice函数

var arr = ["One","Two","Three"];

var arrtoo = arr.slice(0);
arrtoo[1] = "set Map";
document.writeln("数组的原始值:" + arr + "<br />");//Export:数组的原始值:One,Two,Three
document.writeln("数组的新值:" + arrtoo + "<br />");//Export:数组的新值:One,set Map,Three

方法二:js的concat方法

var arr = ["One","Two","Three"];

var arrtooo = arr.concat();
arrtooo[1] = "set Map To";
document.writeln("数组的原始值:" + arr + "<br />");//Export:数组的原始值:One,Two,Three
document.writeln("数组的新值:" + arrtooo + "<br />");//Export:数组的新值:One,set Map To,Three

Obj的深浅拷贝

直接引用,修改了原对象

let conf = {
  adapter:'sqlite',
  db: {
    sqlite:{
      name:'xxx.sqlite'
    },
    mysql:{
      name:'xxx',
      username:'work',
      passwd:'******'
    }
  }
}

//直接引用
let conf2 =conf;
conf2.adapter = 'mysql';
console.log(conf);
console.log(conf2)

浅拷贝

let conf = {
  adapter:'sqlite',
  db: {
    sqlite:{
      name:'xxx.sqlite'
    },
    mysql:{
      name:'xxx',
      username:'work',
      passwd:'******'
    }
  }
}

//浅拷贝
let copied = Object.assign({},conf);
copied.adapter = 'mysql';
console.log(conf.adapter);//"sqlite"
console.log(copied.adapter);//"mysql"
copied.db.sqlite.name ='yyy.sqlite';
//多级属性无法被拷贝,而是引用
console.log(conf.db.sqlite.name);//"yyy.sqlite"
console.log(copied.db.sqlite.name);//"yyy.sqlite"

所以使用深拷贝

let conf = {
 adapter:'sqlite',
 db: {
   sqlite:{
     name:'xxx.sqlite'
   },
   mysql:{
     name:'xxx',
     username:'work',
     passwd:'******'
   }
 }
}

//深拷贝
function deepCopy(des,src) {
 for(var key in src) {
   let prop = src[key];
   if (typeof prop === 'object') {
     des[key] = des[key]||{}; //判断目标对象是否有自身的key
     deepCopy(des[key],prop);
   }else{
     des[key] = src[key];
   }
 }
 return des;
}

let obj1= {
 db:{
   c:"name"
 },
 ad:'ad'
}


let deepCopied = deepCopy(obj1,conf);
let deepCopied2= deepCopy({},conf);
console.log(deepCopied);
console.log(deepCopied2);
deepCopied.db.sqlite.name = 'zzz.sqlite';
console.log([deepCopied.db.sqlite.name,conf.db.sqlite.name]);

//console
[object Object] {
 ad: "ad",
 adapter: "sqlite",
 db: [object Object] {
   c: "name",
   mysql: [object Object] { ... },
   sqlite: [object Object] { ... }
 }
}
[object Object] {
 adapter: "sqlite",
 db: [object Object] {
   mysql: [object Object] { ... },
   sqlite: [object Object] { ... }
 }
}
["zzz.sqlite", "xxx.sqlite"]
上一篇下一篇

猜你喜欢

热点阅读