前期理解
首先,得知道js中的数据类型有:基本数据类型与引用数据类型。
基本数据类型有:Boolean、Number、String、undefined
引用数据类型:Object(Function、Array、Symbol等)
其次,基本数据类型被创建并赋值时,在内存中是存储在栈中的;而引用数据类型,在内存中是存放在堆中的,变量可以理解为有一个指针,指向堆的值。
最后,看一个demo
const obj = {
name: "王五",
age: 18,
};
var a;
var b = a;
b = 1;
console.log(obj.name); //王五
const newObj = obj;
newObj.name = "李四";
console.log(obj.name); //李四
console.log(newObj.name); //李四
console.log(a); //undefined
console.log(b);//1
从代码可以看出,基本数据类型a赋值给b后,b可以重新赋值,不影响a的值。而引用数据类型obj赋值newObj后,newObj的赋值操作会影响Obj原来的值,真是因为obj与newObj指向堆中同一个对象,会互相影响的,这是所谓的浅拷贝。
当我们需要进行复制一个对象,又不影响原对象时,就要使用到深拷贝了。
补充:利用扩展运算符、Object.assign() 实现的也是浅拷贝,因为当原对象包含子对象属性时,就不管用了,利用JSON.parse()和JSON.stringify()也是一样的效果
const obj = {
name: "王五",
age: 18,
info: function () {
console.log(this.name + "在唱歌");
},
son: {
name: "王五的儿子",
},
};
// let newObj = deepCopy(obj);
let newObj = Object.assign({}, obj);
newObj.name = "李四";
newObj.son.name = "李四的儿子";
newObj.info(); // 李四在唱歌
console.log(newObj.name); // 李四
console.log(newObj.son.name); // 李四的儿子
console.log(obj.name); // 王五
console.log(obj.son.name); //李四的儿子
obj.info(); // 王五在唱歌
实现深拷贝的方法
所谓的深拷贝,就是复制原对象,且新对象的任何操作都不影响原对象,等同于在内存中重新创建一个新对象。
function deepCopy(obj) {
let newObj;
let objType = dataType(obj);
if (objType === "Array" || objType === "Object") {
if (objType === "Array") {
newObj = [];
} else {
newObj = {};
}
for (const key in obj) {
if (dataType(obj[key]) === "Object" || objType === "Array") {
newObj[key] = deepCopy(obj[key]);
} else {
newObj[key] = obj[key];
}
}
} else {
newObj = obj;
}
return newObj;
}
//定义函数,来判断需要复制的数据的数据类型,这个函数可判断所有的js数据类型
function dataType(params) {
let typeStr = Object.prototype.toString.call(params);
let endType = typeStr.slice(8, -1);
return endType;
}
const obj = {
name: "王五",
age: 18,
info: function () {
console.log(this.name + "在唱歌");
},
son: {
name: "王五的儿子",
},
};
let newObj = deepCopy(obj);
newObj.name = "李四";
newObj.son.name = "李四的儿子";
newObj.info(); // 李四在唱歌
console.log(newObj.name); // 李四
console.log(newObj.son.name); // 李四的儿子
console.log(obj.name); // 王五
console.log(obj.son.name); //王五的儿子
obj.info(); // 王五在唱歌