深浅拷贝
2020-05-19 本文已影响0人
马甲要掉了
- 浅拷贝
将原对象/原数组的引用直接赋值给新对象/新数组,新对象/新数组只是原对象/原数组的一个引用。 - 深拷贝
将原对象中各项属性的值(数组的所有元素)都拷贝过来,是“值”而不是“引用”,在改变新的数组/对象的时候,不改变原数组/对象。
浅拷贝方法
- Object.assign()
let a = {
age:{
name:2,
}
}
let b = Object.assign({},a);
a.age.name = 22;
console.log(b.age.name) //22
- ...拓展运算符
let a = {
age:{name:2}
}
let b = {..a};
a.age.name = 22;
console.log(b.age.name); //22
浅拷贝只能解决第一层的问题,如果接下去的值中还有对象的话,那么就又回到最开始的话题了,两者享有相同的地址。
深拷贝方法
- Json.parse(Json.stringify(object))
let a = {
name:'qqy',
book:{
title:"Yon don't know JS",
price: '45'}
}
let b = JSON.parse(JSON.stringify(a));
a.name = 'lisi';
b.book.price = '22';
console.log(a);
console.log(b);
image.png
JSON.parse(JSON.stringify()的缺点)
- 手写实现
let obj = {
name:'test',
main:{
a:1,
b:2
},
fn:function(){
},
friends:[1,2,3,[22,33]]
}
function copy(obj){
let newobj = null;
if(typeof obj == 'object' || typeof obj == 'function' && obj !==null){
newobj = obj instanceof Array? []:{};
for(let i in obj){
if(typeof obj[i] === 'object'){
newobj[i] = copy(obj[i]);
}else{
newobj[i] = obj[i]
}
}
}
return newobj;
}
let obj2 = copy(obj)
最终无敌大杀器
function istype(obj,type){//判断包装类型的原型
return Object.prototype.toString.call(obj).indexOf(type)!=-1
}
const deepClone =(initalObj) =>
{
if (typeof initalObj !== 'object') {//如果是基本类型直接返回值
return initalObj
}
if(istype(initalObj,'String')||istype(initalObj,'Number')||istype(initalObj,'Boolean'))
return initalObj.valueOf();
if(istype(initalObj,'Date'))
return new Date(initalObj.valueOf());
if(istype(initalObj,'RegExp')){
let pattern = initalObj.valueOf();
let flags = '';
flags += pattern.global ? 'g' : '';
flags += pattern.ignoreCase ? 'i' : '';
flags += pattern.multiline ? 'm' : '';
return new RegExp(pattern, flags);
}
const obj = Array.isArray(initalObj)?[]:{};//可能是对象或者数组
for (const key in initalObj) {
if (typeof initalObj[key] === 'object') {//对于对象元素,deepclone
//递归返回新的对象
obj[key] = deepClone(initalObj[key]);
} else if (typeof initalObj[key] === 'function') {//对于函数,用bind拷贝
//返回新函数
obj[key] = initalObj[key].bind(obj);
} else {
//基本类型直接返回
obj[key] = initalObj[key];
}
}
return obj;
}