数据存储方式
- 在JS中数据类型有基本数据类型(string, number, boolean, null, undefined, symbol)与引用数据类型(数组,函数,对象)
- 基本数据类型都存放在栈内存中,栈内存中会存放变量的名与值
- 拷贝该基本数据类型会在栈内存中开辟新的空间存放变量的名与值。修改原变量不会影响新的变量
- 而引用数据类型会使用栈内存与堆内存来存放变量,变量的名存放在栈内存中,值存放在堆内存中,栈内存中会存放堆内存中的地址
- 此时拷贝引用数据类型的变量,会在栈内存中开辟空间,存放变量的名,而变量的值仍然会指向堆内存中的同一个,修改原变量会影响拷贝后的变量
浅拷贝
- 浅拷贝拷贝的是对象中的第一级,当修改原变量中的二级或者以上的变量时,会影响拷贝后的变量
- 实现方式:
- 当拷贝中的变量中存在多级,即变量中存在引用数据类型,例如对象的一个属性仍然是一个对象。使用Object.assign()
let a = {
age: 1,
arr: [123, 4, 5]
};
let b = Object.assign({}, a);
let a = {
age: 1,
};
let b = { ...a };
深拷贝
- 拷贝对象中所有级的对象,当修改原变量不会改变新的变量
- 实现方式:
- 使用JSON.parse(JSON.stringfy(obj))实现深拷贝,使用这种方式会忽略undefined与symbol,会忽略函数,不能解决循环引用的对象
let a = {
age: 1,
arr: [1, 2, 3, 4, 55]
};
let b = JSON.parse(JSON.stringify(a));
自封装深拷贝
function deepClone(origin, target) {
if (typeof origin !== "object" || origin) {
return origin;
}
target = target || {}
for (let prop in origin) {
if (target.hasOwnProperty(prop)) {
if (typeof origin[prop] === "object" && origin[prop]) {
if (origin[prop] instanceof Array) {
target[prop] = [];
deepClone(origin[prop], target[prop]);
} else {
target[prop] = {};
deepClone(origin[prop], target[prop]);
}
} else {
target[prop] = origin[prop];
}
}
}
return target;
}