js对象的浅拷贝与深拷贝
浅拷贝和深拷贝都是对于JS中的引用类型而言的,浅拷贝就只是复制对象的引用(堆和栈的关系,原始(基本)类型Undefined,Null,Boolean,Number和String是存入堆,直接引用,object array 则是存入桟中,只用一个指针来引用值,如果拷贝后的对象发生变化,原对象也会发生变化。只有深拷贝才是真正地对对象的拷贝。
1、浅拷贝
默认是浅拷贝,只是将地址进行了复制,示例如下:
//浅拷贝 var obj1={name:"cat"}; var obj2=obj1; obj2.name="pig"; console.log(obj1.name); console.log(obj2.name);
结果:pig
2、深拷贝
深拷贝就是对目标的完全拷贝,不像浅拷贝那样只是复制了一层引用,就连值也都复制了。
只要进行了深拷贝,不会相互影响。
方法一:利用 JSON 对象中的 parse 和 stringify;
注:如果对象中含有一个函数时(很常见),就不能用这个方法进行深拷贝
var obj1 = { name: "cat", show:function(){ console.log(this.name); } }; var obj2 = JSON.parse(JSON.stringify(obj1)); obj2.name = "pig"; console.log(obj1.name); console.log(obj2.name); obj1.show(); obj2.show(); //函数被丢失
方法二:利用递归来实现每一层都重新创建对象并赋值
//对象 var obj1 = { name: "cat", show:function(){ console.log(this.name); } }; //这种深拷贝函数不会丢失 function deepClone(obj) { let objClone = Array.isArray(obj) ? [] : {}; if(obj && typeof obj === "object") { for(key in obj) { if(obj.hasOwnProperty(key)) { //判断ojb子元素是否为对象,如果是,递归复制 if(obj[key] && typeof obj[key] === "object") { objClone[key] = deepClone(obj[key]); } else { //如果不是,简单复制 objClone[key] = obj[key]; } } } } return objClone; } var obj3=deepClone(obj1); //输出cat obj3.show();