JavaScript的深拷贝
javaScript的拷贝有浅拷贝和深拷贝。拷贝我们一般拷贝对象,获取对象的内容(字段、函数)都给复制一遍
浅拷贝:一般只是简单的赋值
//浅拷贝 var obj1={name:"cat"}; var obj2=obj1;//直接赋值给obj2 obj2.name="pig";//修改 console.log(obj1.name); // pig console.log(obj2.name); // pig //obj2与obj1所应用的是同一个对象,只是简单复制对象内容 console.log(obj1 === obj2);//true
由上可知这种直接赋值式的浅复制是复制了同一个内存地址,所以有一个修改了其他也会被修改,因为它们同在一个地址里面。
深拷贝:复制对象的内容创建一个新的对象内容
//深拷贝1、利用 JSON 对象中的 parse 和 stringify var obj3 = { name: "cat", show:function(){ console.log(this.name); } }; var obj4 = JSON.parse(JSON.stringify(obj3)); obj4.name = "pig"; console.log(obj3.name); // cat console.log(obj4.name); // pig obj3.show();//cat //obj4.show(); //函数被丢失,出错
但是我们函数对象没有复制过来,它出错了。为了解决这种问题,我们又有了另外一种深复制——利用递归
递归方法:
//递归方法,进行深拷贝 function deepClone(obj) { //传进来的参数如果是数组选择[],如果不是数组选择{} let objClone = Array.isArray(obj) ? [] : {}; //判断传进来的是不是object类型,如果是基本类型就直接返回。 if(obj && typeof obj === "object") { for(key in obj) {//枚举遍历 if(obj.hasOwnProperty(key)) {//判断obj是否有该名称的属性或对象 //判断ojb子元素是否为对象,如果是,递归复制 if(obj[key] && typeof obj[key] === "object") { objClone[key] = deepClone(obj[key]); } else {//当递归到子元素不是对象时、简单复制 //如果不是,简单复制 objClone[key] = obj[key]; } } } } return objClone; }
我们直接调用这个 递归函数就可以进行深拷贝了
var obj5 = { name: "cat", show: function() { console.log("名称:"+this.name); } }; var obj6 = deepClone(obj5); //调用方法进行复制 obj6.name = "pig"; console.log(obj5.name); // cat console.log(obj6.name); // pig obj5.show(); // cat obj6.show(); // pig