深复制与浅复制
浅复制:复制地址。举个栗子,柜子的第一格有一个苹果,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类型 目标对象,其他对象的成员属性将被附加到该对象上;
object1, objectN: 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);
- 版权声明:文章来源于网络采集,版权归原创者所有,均已注明来源,如未注明可能来源未知,如有侵权请联系管理员删除。