概述
通过学习堆栈内存关系引发的一系列思考,对此进行知识总结。
案例一:基础类型复制
let a = 1 // 创建一个栈内存空间
b = a // 赋值a的栈内存空间
b = 2 // 创建一个新的栈内存空间
console.log(a)
console.log(b)
结果:
1
2
案例二:引用类型复制
let a = {name: 'weili', age: '18'} // 创建一个对象,地址存储在栈中,内容在堆中新创建一个内存空间存放
b = a // 赋值a引用内存的地址
b = {name: 'xiaoye', age: '20'} // 新建一个对象,另起一个地址与堆存储空间
c = a// 赋值a引用内存的地址
c.name = 'xiaohong' // 修改a引用内存地址中堆的数据内容,c地址没变,依旧指向a
console.log(a)
console.log(b)
console.log(c)
结果:
{ name: 'xiaohong', age: '18' }
{ name: 'xiaoye', age: '20' }
{ name: 'xiaohong', age: '18' }
案例三:浅拷贝
let a = {name: 'weili', age: '18',student:{'number':1}} // 创建一个对象
let b = Object.assign({}, a) // 浅拷贝一个对象,只新创建了第一层对象地址指向,只对第一层数据新建内存空间
b.age = 20 // 修改b中内存空间数据,只有b内容才会受影响
b.student.number = 2 // 修改b中number数据,由于a与b指向一个内存空间,所以两边都会发生变化
console.log(a)
console.log(b)
结果:
{ name: 'weili', age: '18', student: { number: 2 } }
{ name: 'weili', age: 20, student: { number: 2 } }
案例四:深拷贝
/**
* 简单版深拷贝
*/
function deepClone(obj) {
// 如果obj类型不是引用类型则直接返回数值
if(typeof obj !== "object") {
return obj
}
// 判断对象类型
var objClone = Array.isArray(obj) ? [] : {};
// 遍历对象内容
for(key in obj) {
// 判断obj是否有属性key
if(obj.hasOwnProperty(key)) {
// typeof null 为object,所以需要判断obj[key]
if(obj[key] && typeof obj === "object") {
// 递归深入查找对象
objClone[key] = deepClone(obj[key])
} else {
objClone[key] = obj[key]
}
}
}
return objClone
}
let a = {name: 'weili', age: '18',student:{'number':1},arr:[1,2,3]}
let b = deepClone(a) // 主要是将所有的堆内存空间复制一份,防止数据互相影响
b.age = 20
b.student.number = 2
b.arr[0] = 4
console.log(a)
console.log(b)
结果:
{ name: 'weili', age: '18', student: { number: 1 }, arr: [ 1, 2, 3 ] }
{ name: 'weili', age: 20, student: { number: 2 }, arr: [ 4, 2, 3 ] }