一、回顾变量类型
基础类型
boolean(bool)
number
string
null
undefined
引用类型
object
function
array
基本类型与引用类型的存储
基本类型一般存储在 栈 (栈小)
- 栈一旦确认 大小就固定 可能会造成溢出
- 栈一般是先进后出
- 用于存储基础类型以及引用类型的堆地址
- 运行速度快
引用类型一般存储在 堆(堆大)
- 堆大小不确认 可以扩展
- 不允许js直接操作堆数据
- 无序存储
- 由于其大小不固定 顺序不固定 导致 速度慢
堆栈示意图
栈内容当程序运行完毕 栈就空了
但是堆内容不见的一定就空 可能会出现 没有任何指针指向堆内容 导致都变成垃圾
所以我们需要手动指向 null让其销毁
二、深浅拷贝
深浅拷贝分两种情况 引用类型 基础类型
基础类型都是深拷贝
引用类型 大多数是浅拷贝 也可以变成深拷贝
深拷贝 地址不同 一个改变另一个并不跟随发生变化就是深拷贝 拷贝内容 地址不同
浅拷贝 地址相同 一个改变另一个随之改变 就是浅拷贝 拷贝的是地址
深拷贝
let a = 10;
let b = a;
console.log(1,a,b,a===b);
a = 88;
console.log(2,a,b,a===b);
console.log("======================");
浅拷贝
let obj1 = {
n : 88
}
let obj2 = obj1;
console.log(1,obj1,obj2,obj1===obj2);
obj1.a = 99;
console.log(2,obj1,obj2,obj1===obj2);
实现深拷贝 array object
1.JSON.stringify JSON.parse
let obj1 = {
n : 88
}
let obj2 = JSON.parse(JSON.stringify(obj1)); //深拷贝
console.log(1,obj1,obj2,obj1===obj2);
obj1.a = 99;
console.log(2,obj1,obj2,obj1===obj2);
2. ... 解构
let arr1 = [1,5,6,7];
let arr2 = [...arr1];
console.log(1,arr1,arr2,arr1===arr2);
arr1[0] = "222"
console.log(2,arr1,arr2,arr1===arr2);
// 伪拷贝 一般情况下是 第一层深拷贝 后面层浅拷贝
let arr1 = [1,2,3,[6,7,8]];
let arr2 = arr1.slice();
console.log(1,arr1,arr2,arr1 === arr2);
arr1[0] = 180;
arr1[3][0] = 666;
console.log(2,arr1,arr2,arr1 === arr2);
let arr1 = [1,2,3,[6,7,8]];
let arr2 = arr1.concat();
console.log(1,arr1,arr2,arr1 === arr2);
arr1[0] = 180;
arr1[3][0] = 666;
console.log(2,arr1,arr2,arr1 === arr2);
let menu1 = {
menu: "菜单",
item:{
type: "menu",
name: "子菜单"
}
}
// Object.assign(目标,源)
let menu2 = Object.assign({},menu1)
console.log(1,menu1,menu2,menu1 === menu2);
menu1.menu = "编辑"
menu1.item.name = "保存"
console.log(2,menu1,menu2,menu1 === menu2);
想要解决真正意义上的拷贝咋办
扁平化 嵌套的多层想办法给他变成地扁平化 递归思想
递归思想
普通的 按正常处理
深度的(引用类型 )按递归处理 直到没有引用类型为止··
let woniu = {
name: "张三",
age: 8,
school: [
{
id: 1,
name: "清华校区"
},
{
id: 2,
name: "北大校区"
},
{
id: 3,
name: "上交校区"
},
{
id: 4,
name: "国科大校区"
}
],
subject: {
web: "web前端",
java: "java后端",
python: "python",
ui: "设计"
}
}
function copyData(source) {
// 定义一个容器 容器需要根据源来决定 源是对象 你就是你对象 源是数组你就是数组
let result = Array.isArray(source) ? [] : {};
for (const item in source) { // 遍历源 对象与数组的统一遍历方式是 for in
if (typeof source[item] === "object") { //区分引用类型与普通类性别 引用类型继续处理(遍历)基本类型直接返回
result[item] = copyData(source[item])
} else {
result[item] = source[item];
}
}
return result; // 最终将结果返回
}
let fanyun = copyData(woniu);
console.log(1,woniu,fanyun);
woniu.subject.web = "web大前端"
woniu.school[0].name = "总校区"
console.log(2,woniu,fanyun);