js 深拷贝和浅拷贝

js 深拷贝和浅拷贝

先举一下项目中遇到的两个例子:

例子1:


var json = $.parseJSON(data.data); 
//data.data是后台返回的值 
var a = json.channels;
var b = json.channels;
console.log(a===b)//true

这个例子是浅拷贝,a、b两个对象是完全相等的,指向的内存地址也是一样的,a和b会互相影响,当b对象改变时,a也会跟着改变。

在项目中就吃了这个亏,a对象本来想要存一个原始值,b是一个在原始值上会变动的数组,最后a和b会进行对比,但是发现这两个一直都是b修改后的最新数组,最后修改方式为下一个例子


例子2:


var json = $.parseJSON(data.data);
var a = $.parseJSON(data.data).channels;
var b = $.parseJSON(data.data).channels;
console.log(a === b);//false

这个例子是深拷贝,a、b两个对象指向的内存地址是不一样的,当赋值的时候同时给对象开了新的内存地址,所以判断的时候是false。a和b两个对象由于指向的内存地址不一样了所以不会互相影响


浅拷贝:一般是直接对(object、array)属性的拷贝,如例子一就是直接对json这个对象里的channels属性进行了拷贝,这样的拷贝是会互相影响值

深拷贝:如果想要互不影响达到深拷贝效果可以采用以下方法:

  • Array.prototype.slice(),
  • Array.prototype.concat(),
  • jQury的$.extend({},obj)
  • JSON.parse(),
  • JSON.stringify(),
  • jQury的$.extend(true,{},obj),
  • lodash的_.cloneDeep
  • _.clone(value, true)

举一个示范例子:


var a = {c:1};
var b = $.extend(true,{},a);
var d = a;
console.log(a===b);//false
console.log(a===d);//true
a.c = 2;
console.log(b.c);//1 深拷贝 没有受到a影响,所以仍为1
console.log(d.c);//2 浅拷贝 受到a影响,所以改成2

其实整篇最根本原因是对象的内存分配问题,这个将会在下一篇具体说明~

posted @ 2017-12-14 14:22  liaoanran  阅读(454)  评论(1编辑  收藏  举报