JavaScript中会用到深拷贝和浅拷贝的情况:使引用类型的使用互不影响。
简单了解一下基本类型和引用类型的区别:
- 基本数据类型和引用类型的区别
基本数据类型: String,Boolean,Number,Undefined,Null;占用空间固定,保存在栈中。不管是进行赋值、浅拷贝、深拷贝都仅仅是把值赋值给对方,相互之间不受影响。如:
let a = 12; //=>undefined
let b = a; //赋值
b = 14; //=>14
a // =>12
b //=>14
引用类型 :array object function,引用类型是一种数据结构,用于将数据和功能组织在一起。占用空间不固定,保存在堆中;如果进行直接赋值的话,变量会指向同一个地址,当这个变量改变的时候,原变量也会受到影响。
如:
let person = {
age:13
};
let person_1 = person;
person_1.age = 14;
person // =>{age: 14}
上述代码person是一个对象,同时也是一个引用类型,如果引用类型进行简单的赋值的话,如person_1,当进行修改person_1的时候,person对象也发生了改变。
划重点: 开发中我们真有需要“复制”一个这样的互不影响的引用类型,应该怎么做到呢?那就需要用到JavaScript中的浅拷贝和深拷贝来实现了。
这两者有什么的区别呢?
浅拷贝: 会得到一个新的变量,但是它仅仅只是复制了某个对象的头指针,并不改变子对象的指针,还存在共享同一块内存的子对象。
浅拷贝的方式:
1.Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
Object.assign(target, ...sources)
2.ES6
let target= {...sources};
如:
let person = {
age:13,
own:{
phone:'ios'
}
};
// Object.assign({},)
let person_1 = Object.assign({}, person);
person_1.age = 14;
person_1.own.phone= 'Android';
person // =>{age: 13, own: {phone:'Android'}}
//es6中可以这样实现浅拷贝
let person_2 = {...person};
person_2.own.phone = 'none';
person // =>{age: 13, own: {phone:'none'}}
从代码中可以看到子对象还互相影响。如果想要子对象也互不关联,那就需要用到深拷贝了。
深拷贝: 会拷贝创造出一个一模一样的对象,新旧对象不共享内存,修改新对象不会改到原对象。
实现方式:
JSON.parse(JSON.stringify(object))
如:
let person = {
age:13,
own:{
phone:'ios'
}
};
let person_1 = JSON.parse(JSON.stringify(person));
person_1.age = 14;
person_1.own.phone='none';
person //=>{age: 13, own: {phone: 'ios'}}
局限性:
会忽略 undefined : 如果原对象中,有属性的值是undefined,深拷贝的时候,会忽略掉。
如:
let person = {
age:13,
name:undefined,
own:{
phone:'ios'
}
};
let person_1 = JSON.parse(JSON.stringify(person));
person_1 // =>{age: 13,own:{phone: "ios"}}
person //=>{age:13,name:undefined,own:{phone:"ios"}}
不能序列化函数:也就是不能使用JSON.parse()、JSON.stringify()进行转化的对象
不能解决循环引用的对象:对象内部属性的值 循环 利用内部其他属性的值。
- JSON.parse(JSON.stringify(person))基本能够解决大部分问题,
- 如果对象中含有上述问题不能进行深拷贝,可以尝试使用
lodash.cloneDeep 进行深拷贝
- 使用递归进行深拷贝
export function deepClone(obj) {
let obj_1 = {};
for (let key in obj) {
if (Object.prototype.toString.call(obj[key]) === '[object Object]') {
obj_1[key] = deepClone(obj[key]);
} else {
obj_1[key] = obj[key];
}
}
return obj_1;
}
2084

被折叠的 条评论
为什么被折叠?



