平时项目中我们总会用到一些需要存储备份的时候,这时需要将数组或对象克隆下来,根据需求不同会选择不同的拷贝方式,一般浅拷贝项目中不常用(个人而言)深拷贝的话使用较多,那么他们到底有什么区别呢?
很多前端面试中都会涉及到克隆,有时也叫拷贝,一般教程都会从js中的基本数据类型和引用数据类型讲起,很容易查到,我们直接往后说,之前看到过一个说法很容易理解:
浅层克隆只复制一层,深层次的对象级别的克隆引用
深层克隆是拷贝多层,每一级别的数据都会拷贝出来
复杂情况下(对象属性值中存在又是引用值的情况)浅层克隆后,其中一个对象属性值变动都会引起另一个对象属性值的变动,备份肯定是不希望这种情况发生,所以需要深度克隆解决这个问题。
校招的时候做过很多面试题都会让我列举出至少两个浅层克隆,不用也需要好好了解一下呀,于是一顿查阅,然后梳理了三个方法供参考。
首先 var 一个原始对象 object 放在那。
var object = {
myName: "taozi",
myHabby: "pipa",
myAge: 20,
myFamily: ["father", "mother"],
mywork:{
gowork:"9:00",
backhome:"22:00"
}
}
function shallowClone(obj1) {
var obj2 = {
};
for (const key in obj1) {
if (object.hasOwnProperty(key)) {
obj2[key] = obj1[key];
}
}
return obj2;
}
然后拿myObject装obj2的值
var myObject = shallowCopy(object);
console.log(myObject);
一起康康结果,没问题复制过来了
再试试改变拷贝过来的对象中数组其中一个值。
myObject.myFamily[0] = "dad";
console.log(myObject.myFamily[0]);
console.log(object.myFamily[0]);
克隆过来的属性值变了,原对象里的属性值也变了。
说明是浅克隆,同理验证其他两个浅克隆方法。
var obj1 = Object.assign({
},object);
console.log(obj1);
var obj1 = {
...object};
console.log(obj1);
var obj1 = JSON.parse(JSON.stringify(object));
console.log(obj1);
还是接着上面浅拷贝我创建了一个object对象,然后执行这段代码
然后分别检验下object原对象里边的数组(myFamily)和对象(myWork)是否随着原数组改变
object.myFamily[1] = "mam";
console.log(obj1.myFamily[1]);
console.log(object.myFamily[1]);
obj1.mywork.gowork = "九点";
console.log(obj1.mywork.gowork);
console.log(object.mywork.gowork);
可见,object(原对象)和obj1(克隆对象)中的对象级别属性值不是引用了同一个,所以深度克隆算是成功,但学习过程中发现这种方法有很多开发中可能会遇到的坑,具体可以参考一下
关于JSON.parse(JSON.stringify(obj))实现深拷贝应该注意的坑
也可以自行百度。
deepClone = obj1 => {
const obj2 = obj1.constructor === Array ? [] : {
};
for (let key in obj1) {
if (obj1.hasOwnProperty(key)) {
if (obj1[key] && typeof obj1[key] === 'object') {
obj2[key] = obj1[key].constructor === Array ? [] : {
};
obj2[key] = deepClone(obj1[key]);
} else {
obj2[key] = obj1[key];
}
}
}
return obj2;
}
var objectTarget = deepClone(object);
思路是:判断要克隆的是数组还是对象 --> 遍历 --> 如果还有引用类型数据 --> 进入里边遍历每一个属性值 --> 直到里边全是普通类型数据值 --> 将每项添加到obj2中 --> 结束遍历返回obj2的值。
最后检验下
console.log(object === objectTarget);
console.log(object.mywork === objectTarget.mywork);
console.log(object.fn === objectTarget.fn);
浅层克隆:
- 利用 for in 函数
- 利用Object.assign
- 解构赋值{…obj1}
深层克隆:
- JSON.parse(JSON.stringify(object))
- 递归函数
我是程序媛小桃,我在这里记录成长,欢迎多多指正,欢迎一起讨论