遇到问题:
首先来看这段代码
let a = 1;
let b = a;
a = 2;
console.log(a,b);
image.png
然后再看这段代码
~~按道理来说b应该不会改变的,然而事实它却改变了~~
let a = [1, 2, 3, 4, 5];
let b = a;
a[0] = 2;
console.log(a, b);
image.png
知识点:
对比上面两个例子,就牵扯到了以下几点:
栈堆:具体可以参考 此篇文章,其中有针对 基本数据 与 复杂(引用)数据 的解释
基本数据类型:number,string,boolean,null,undefined,symbol以及未来ES10新增的BigInt(任意精度整数)七类
引用数据类型:无序对象{a:1},数组[1,2,3],以及函数等
深拷贝与浅拷贝:简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力
解决问题:
方法1:
点击参考 es6中扩展运算符(...)
下面只是针对遍历一层的拷贝来解决的问题。
实际上, 展开语法和 Object.assign() 行为一致, 执行的都是浅拷贝(只遍历一层)
//数组
let b = [...a];
//对象
let b = {...a};
方法2:
采用递归递归的方式,去复制所有层级属性
这里封装一个深拷贝的函数(只是一个基本实现的展示,并非最佳实践)
function deepClone(obj){
let objClone = Array.isArray(obj)?[]:{};
if(obj && typeof obj==="object"){
for(key in obj){
if(obj.hasOwnProperty(key)){
//判断ojb子元素是否为对象,如果是,递归复制
if(obj[key]&&typeof obj[key] ==="object"){
objClone[key] = deepClone(obj[key]);
}else{
//如果不是,简单复制
objClone[key] = obj[key];
}
}
}
}
return objClone;
}
let a=[1,2,3,4];
let b=deepClone(a);
a[0]=2;
console.log(a,b);
image.png
方法3:
除了递归,我们还可以借用JSON对象的parse和stringify
function deepClone(obj) {
let _obj = JSON.stringify(obj);
let objClone = JSON.parse(_obj);
return objClone
}
let a = [1, 2, 3, 4];
let b = deepClone(a);
a[0] = 2;
console.log(a, b);
image.png
以上内容都是参考了 深拷贝与浅拷贝的区别,实现深拷贝的几种方法 文章受益匪浅,想了解更多的,大家可以去看原文章~~
网友评论