一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情。
本文将详解深拷贝与浅拷贝的实现方法和相应的优缺点
首先我们需要弄清楚两种数据类型:
基础类型:数值、字符串、布尔、null、undefined
var a = =100;
var b = a;
a = 50;
console.log(b);//100
基础类型,遇到 = 时,就是值的复制,存储地方在栈中
引用类型:统称为Object类型,细分有Object类型,Array类型,Date类型,Function类型等。
var obj1={
a:1;
}
var obj2 = obj1;
obj2.a=2;
console.log(obj1.a)
对象类型,遇到 = 时,是内存地址的复制,所以改变obj2的值,obj1也会跟着改变
深拷贝与浅拷贝
浅拷贝:复制了地址,原来的变量和新建的变量指向了堆区的同一处地方,彼此会相互影响
深拷贝:在堆区中重新分配内存,原来的变量和新的变量指向不同的地址,虽然值现在相同,但是互不影响
浅拷贝的实现方法:
-
对象之间直接用等号赋值
var obj1={ a:1; } var obj2 = obj1; -
以下方法可以处理一层的深拷贝,但是如果对象里又嵌套了对象,则内层的对象依旧只复制了地址(浅拷贝)
- Object.assign()
var hd = { name:"小周", age:19 }; var obj = Object.assign({},hd);- 展开表达式 语法:
新对象={...被拷贝的对象}
var hd = {
name:"小周",
age:19
};
var obj = {...hd};
- for循环进行浅拷贝
var hd ={
name:"小周",
age: 19,
};
var obj = {};
for (const key in hd) {
obj[key] = hd[key];
}
深拷贝的实现方法:
-
自己一个字一个字的敲代码进行拷贝 优点:方便增删查改 缺点:很麻烦,得手动一个一个敲出来
-
将js对象先转化成json中的字符串,然后再转成js,就可以实现深拷贝
var json = JSON.stringify(obj1); var js = JSON.parse(json);可也将两行代码合并成一行:
var obj2 = JSON.parse(JSON.stringify(obj));优点:简单方便
缺点:对象中的函数和正则表达式无法拷贝
-
递归
function deepClone(newObj, obj) { //遍历obj的每一个成员,赋值给newObj for (var keys in obj) { if (obj[key] instanceof Array) { //数组,引用类型 newObj[key] = []; deepClone(newObj[key], obj[key]); } else if (obj[key] instanceof Object) { //对象:引用类型 newObj[key] = []; deepClone(newObj[key], obj[key]); } else { //值类型 newObj[key] = obj[key]; } } }
递归的思路: 因为引用类型有:数组,对象,所以我们在递归的时候需要判断一下,如果是引用类型的话,进一步递归深拷贝,如果只是值类型,则直接拷贝给新对象就行
- 遍历obj的每一个成员,赋值给newObj
- if来判断 obj 是否是array数据类型,如果是,就给newObj[key]new一个新的对象,然后递归深拷贝
- if来判断 obj 是否是对象数据类型,如果是,就给newObj[key]new一个新的对象,然后递归深拷贝 4.if判断如果是值类型,如果是,就直接拷贝。