我们需要了解值类型,和引用类型
基本数据类型(值类型)
1.String 字符串
2.number 数字
3.boolean 布尔 true false
4.null 定义赋值为null
5.undefind 定义未赋值
引用类型
1.Object 对象
2.array 数组 一种特殊的对象(索引)
3.function 一种特殊的对象(可执行)
值类型和引用类型的区别
![](https://i-blog.csdnimg.cn/blog_migrate/207aadb9bee24063630cb6f6c7d46e47.png)
值类型:
1.占用空间固定,保存在栈中2.保存和复制的都是值得本身3.基本数据类型都是值类型4.一个方法在执行时会创建一个内存栈,并在执行结束后自然销毁,栈里面存储得时基础变量和一些对象得引用得变量,基础变量得值是存储在栈中,而引用变量存储在栈中得指向堆中得数组或者对象得地址,这就是为什么修改引用类型总会印象到其他这个动作的引用变量
引用类型:
1.占用空间不固定,保存在堆2.保存和复制的是指向对象的一个指针3,堆内存的对象不会随方法的结束而被销毁,即使方法结束后,这个对象还可能被另一个引用变量所使用,那么这个对象依然不会销毁,只有一个对象没有任何引用变量引用他时,系统的垃圾回收机制才会核实的时候回收他
3.手写深拷贝
const str = {
name: '杨某某',
school: {
class: '一般'
},
age: [1, 2, 4, 5, 6],
fu: function aa() {
console.log('aaaa');
}
}
第一种
const strs = JSON.parse(JSON.stringify(str))
strs.name = '夏天'
console.log(strs, str);
从这里可以看出一个弊端,就是会把fu这个方法给清除掉(一般还会有正则)
第二种 (通过递归方法)
function deepclone(str) {
if (typeof str !== 'object' || str == null) {
return str
}
let res = str instanceof Array ? [] : {}
for (const key in str) {
if (str.hasOwnProperty(key)) { //监测是否是自身属性
//res[key] = str[key] //这样写只执行了一层,如果嵌套多层,后面就是引用,后面都会发生更改
res[key] = deepclone(str[key])
console.log(str[key]);
}
}
return res
}
const arrs = deepclone(str)
arrs.school.class = '二班'
console.log(arrs, str);