javascript中存储对象都是存地址的。javascript
浅拷贝:浅拷贝是都指向同一块内存区块,浅拷贝共用同一内存地址,你改值我也变。若是拷贝的对象里面的值是一个对象或者数组,它就是浅拷贝,拷贝的知识引用地址。 js的Object.assign,jquery的extend方法都是浅拷贝,通常的等号赋值也是浅拷贝 。html
上面vue里面的两个写法也是浅拷贝,具体地址为 https://cn.vuejs.org/v2/guide/list.html
vue
深拷贝:深拷贝则是另外开辟了一块区域,深拷贝是互不影响,你改值我也不变。angular里面的 angular.copy 是深拷贝。java
下面实例也能够看出这一点:jquery
// 浅拷贝 const a = {t: 1, p: 'gg'}; const b = a; b.t = 3; console.log(a); // {t: 3, p: 'gg'} console.log(b); // {t: 3, p: 'gg'}
//深拷贝 const c = {t: 1, p: 'gg'}; const d = deepCopy(c); d.t = 3; console.log(c); // {t: 1, p: 'gg'} console.log(d); // {t: 3, p: 'gg'}
能够明显看出,浅拷贝在改变其中一个值时,会致使其余也一块儿改变,而深拷贝不会。数组
// Cloning an object var obj = { a: 1 }; var copy = Object.assign({}, obj); console.log(copy); // { a: 1 }
// Merging objects var o1 = { a: 1 }; var o2 = { b: 2 }; var o3 = { c: 3 }; var obj = Object.assign(o1, o2, o3); console.log(obj); // { a: 1, b: 2, c: 3 } console.log(o1); // { a: 1, b: 2, c: 3 }, target object itself is changed. console.log(o2);//{b: 2} 源对象没有变 console.log(o3);// {c: 3}
是否是很完美,又能够clone又能够merge。在我这种状况下,我以为个人代码量又能够减小了,好比:ide
const defaultOpt = { title: 'hello', name: 'oo', type: 'line' }; // 原来可能须要这样 const opt1 = deepCopy(a); opt1.title = 'opt1'; opt1.type = 'bar'; opt1.extra = 'extra'; // 额外增长配置 // 如今只要这样 const opt2 = Object.assign({}, a, { title: 'opt2', type: 'bar', extra: 'extra' });
注:它只对顶层属性作了赋值,彻底没有继续作递归之类的把全部下一层的属性作深拷贝。意思就是是拷贝一层,没有拷贝多层。
一层 { a: 1, b: 2, } 多层 { a: 1, b: 2, c: { d: 4, e: { f: 6, g: 7 } } }
实现深拷贝,遍历key
function deepClone(obj){ //判断obj是否为数组,若是是,初始化数组[],不然初始化对象{} let dcObj = Array.isArray(obj)?[]:{}; if(obj && typeof obj==="object"){ //循环 for(key in obj){ //判断对象是否有key属性 if(obj.hasOwnProperty(key)){ //判断ojb子元素是否为对象,若是是,递归复制 if(obj[key]&&typeof obj[key] ==="object"){ dcObj[key] = deepClone(obj[key]); }else{ //若是不是,简单复制 dcObj[key] = obj[key]; } } } } return dcObj; }; let t1 = { "a": 1, "b": 2, "c": { "d": 4, "e": { "f": 6, "g": 7 } } }; let t2=deepClone(t1); t1.a=6; console.log(t1); /* { "a": 6, "b": 2, "c": { "d": 4, "e": { "f": 6, "g": 7 } } } */ console.log(t2); //t1深拷贝给t2, b属性的值仍是为2,没有改变,因此是深拷贝 /* { "a": 1, "b": 2, "c": { "d": 4, "e": { "f": 6, "g": 7 } } } */