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