深复制与浅复制

浅复制:复制地址。举个栗子,柜子的第一格有一个苹果,A手里有一张写着苹果放置位置的纸条,B将A的纸条抄录了一份,此时苹果还是只有一个,如果B根据纸条写的位置去咬一口苹果,那么,当A再根据纸条去找到苹果时,这个苹果就是被咬过的苹果。

	let a={name:'张三',age:20};     //这里的a是变量,该变量中是指向堆中{name:'张三',age:20}对象的存储地址          let b=a;  //此时b只复制了a变量中的地址,a与b指向同一个对象          console.log(a);  //{name: "张三", age: 20}     console.log(b);  //{name: "张三", age: 20}     console.log(a===b); //true          b.name='b修改了名字';   //通过b修改对象的name属性          console.log(a);  //{name: "b修改了名字", age: 20}     console.log(b);  //{name: "b修改了名字", age: 20} 

以上代码中b只 复制 了a变量中的 地址,a与b指向 同一个对象,因此通过b修改指向对象的属性后输出a,b都是被修改后的对象。

深复制:复制值,即将 复制 对象的 内容 都复制过来,产生一个 新的对象。举个栗子,用放在柜子第一格的苹果a克隆出一个一模一样的苹果b,并将苹果b放在柜子第二格,这两个苹果虽然长得一模一样,但不能说a和b是同一个苹果,就算咬一口苹果b,也只有苹果b上有牙印,苹果a不会受到影响。

console.log({name:'张三'}==={name:'张三'});  //false 

深复制的方法

1. JSON.parse(JSON.stringify(obj)) 实现深复制

JSON.stringify将对象转换为字符串,再通过JSON.parse将其还。
注意: 此方法仅适用于一般数据的拷贝,如对象、数组。

let person = {         name:'张三',   //一级属性         sex:'男',         friend:{             name:'李四',   //二级属性             sex:'女',         } }; let personCopy=JSON.parse(JSON.stringify(person)); console.log(personCopy); 

personCopy打印结果:
【笔记】深复制与浅复制
验证是否深复制:

personCopy.name = '修改名字'; personCopy.friend.name = '修改朋友名字';      console.log(person); console.log(personCopy); 

深复制完成:
【笔记】深复制与浅复制

2. Object.assgin() 实现深复制

注意: Object.assgin()只能 深复制一级属性,当二级属性为引用数据类型的时候就是 浅复制二级属性

let person = {         name:'张三',   //一级属性         sex:'男',         friend:{             name:'李四',   //二级属性             sex:'女',         } };  let newPerson = Object.assign({},person);   //使用Object.assgin()将person复制给newPerson console.log(newPerson); 

newPerson打印结果:
【笔记】深复制与浅复制
此时,newPerson将person的一级属性进行了深复制二级属性仍然只进行了浅复制,证明如下:

newPerson.name='改变一级属性';  //newPerson改变一级属性 newPerson.friend.name='改变二级属性';  //newPerson改变二级属性  console.log(person);   console.log(newPerson);   

深复制一级属性,二级属性仍为地址:
【笔记】深复制与浅复制

3. for in 递归实现深复制

let thisObj = { 	name:'张三', 	like:{     	ball:'篮球',     	eat:'西红柿炒鸡蛋', 	} };  //写一个递归深复制的方法 function clone(obj) {     let newObj = {};     for (let key in obj){         if (typeof obj[key]==='object'){  //如果obj的该项数据类型依然为对象             newObj[key]=clone(obj[key]);  //调用自己,该项再次进入判断、复制         }else {             newObj[key] =obj[key]         }     }     return newObj; }      let newObj = clone(thisObj); console.log(thisObj);  console.log(newObj);   

复制后打印结果:
【笔记】深复制与浅复制
验证是否深复制:

newObj.name='修改名字';  //修改一级属性 newObj.like.ball='修改篮球';   //修改二级属性  console.log(thisObj);   console.log(newObj);  

深复制完成:
【笔记】深复制与浅复制
4. jquery的extend方法实现深复制

$.extend( [deep ], target, object1 [, objectN ] )

deep : 布尔值,默认为false(不支持第一个参数传递false),为true时为深拷贝,为false时不会深度合并对象;
target: Object类型 目标对象,其他对象的成员属性将被附加到该对象上;
object1objectN: Object类型 被合并的对象。

false举例:

let newPerson = {}; $.extend(newPerson,person);  console.log(newPerson); console.log(newPerson===person); 

输出:
【笔记】深复制与浅复制
验证未深度合并:

newPerson.name='修改'; newPerson.friend.name='修改';  console.log(person); console.log(newPerson); 

【笔记】深复制与浅复制
true举例:

let newPerson = {};     $.extend(true,newPerson,person);          console.log(newPerson);     console.log(newPerson===person); 

输出:
【笔记】深复制与浅复制
验证深复制:

newPerson.name='修改'; newPerson.friend.name='修改';  console.log(person); console.log(newPerson); 

【笔记】深复制与浅复制

  • 版权声明:文章来源于网络采集,版权归原创者所有,均已注明来源,如未注明可能来源未知,如有侵权请联系管理员删除。

发表回复

后才能评论