JS的深拷贝和浅拷贝
近日在做项目时发现一个很有趣的问题,我用jquery的ajax从后台得到一串JSON格式的字符串A,然后我想复制一份新的B,用来保存的时候对这两个字符串进行比较,然后记录那些字段被修改了,结果在比较的时候发现A永远等于B,网上查了之后才发现JS中数组的复制有两种方式,深拷贝和浅拷贝。下面就来了解下:
js的数据类型分为两种,基本类型和引用类型:
1、基本类型值(数值、布尔值、字符串、null和undefined):指的是保存在栈内存中的简单数据段。
2、引用类型值(对象、数组、函数、正则):指的是那些保存在堆内存中的对象,变量中保存的实际上只是一个指针,这个指针执行内存中的另一个位置,由该位置保存对象。
只有在复制引用类型值的时候才会区分 深拷贝和浅拷贝,而复制基本类型值不需要区分。
浅拷贝与深拷贝的区别
浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存(操作新旧对象时会相互影响)。
但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。
下面总结深拷贝的几种方式,浅拷贝就不重复啰嗦了:
1、采用递归的方式来复制新的对象
var a = [1, 2, 3, 4];
function deecClone(obj){
var objClone = Array.isArray(obj)?[]:{};
if(obj && typeof(obj) == "object"){
for(key in obj){
if (obj[key] && obj[key] === "object") {
objClone[key] = deepclone(obj[key]);
}else{
objClone[key] = obj[key];
}
}
}
return objClone;
}
var b =deecClone(a); //此处得到的b与a将不再共享同一块内存
2、用JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象。
var a = [1, 2, 3, 4];
var b = JSON.parse(JSON.stringify(a)); //此处得到的b与a将不再共享同一块内存
总结:
浅拷贝:复制某个对象的指针,而不是对象的本身,新旧对象共享一块内存。
深拷贝:复制并创建一个一模一样的对象,不共享内存,修改新对象,旧对象不变。
实现深拷贝的方式有两种:
1.递归
2.JSON.stringify结合JSON.parse