JavaScript 中堆和栈的区别
JS变量都存放在内存中,而内存给变量开辟了两块区域,分别为栈区域和堆区域栈像个容器,容量小速度快堆像个房间,容量较大讲这些之前我们先说说基本数据类型和引用数据类型我们知道在js中的数据类型可以分为基本类型和引用类型。基本类型是存在栈内存中的,引用类型是存在堆内存中的,但是引用类型的引用还是存在栈内存中的。let num1 = 1;num1 = 2;console.log(num1);// 2con
JS变量都存放在内存中,而内存给变量开辟了两块区域,分别为栈区域和堆区域
栈像个容器,容量小速度快
堆像个房间,容量较大
讲这些之前我们先说说基本数据类型和引用数据类型
我们知道在js中的数据类型可以分为基本类型和引用类型。基本类型是存在栈内存中的,引用类型是存在堆内存中的,但是引用类型的引用还是存在栈内存中的。
let num1 = 1;
num1 = 2;
console.log(num1); // 2
const p1 = {
name: 'Tom',
age: 20
}
const p2 = p1;
p2.name = 'oakley';
console.log(p1.name); // "oakley"
基本类型 声明一个变量,多次赋值就会取取最后一个值
基本类型 可以直接复制,复制之后的内容和原内容没有什么联系,类似于开辟了一个新的空间
引用类型 直接赋值给另一个变量以后相互之间的修改会互相影响对方,进而引出浅拷贝与深拷贝的问题
基本类型 不能添加属性或者方法,而引用类型可以动态添加或删除属性/方法
栈
学过数据结构的都知道 栈 是一种 先进后出 的数据结构,栈内存是内存中用于存放临时变量的一片内存块。当声明一个基本变量时,它就会被存储到栈内存中。比如有这样一段代码,他们在栈内存中存储的形式如下表一样:
const a = 1;
const b = "1";
变量名 | 变量值 |
---|---|
b | “1” |
a | 1 |
而当其发生复制时,会把对应内存中的数据复制一份到新内存中,就像下面这样
const c = b
变量名 | 变量值 |
---|---|
c | “1” |
b | “1” |
a | 1 |
很显然,c,b两个变量占用了不同的存储空间,所以他们之间也并没有什么联系。
栈内存的地址分配是连续的,所以在后续也不能对其进行进一步的扩充或者删除。
栈总结:
栈内存的特点:存取速度快,但不灵活,同时由于结构简单,在变量使用完成后就可以将其释放,内存回收容易实现。
堆
堆内存的存储不同与栈,虽然他们都是内存中的一片空间,但是堆内存存储变量时没有什么规律可言。
const p1 = {};
const p2 = {};
const p3 = {};
我们在访问引用类型时,需要在栈内存中查找 对应的地址,在去堆内存中取得真正的值,访问速度自然不及栈内存。
对引用类型进行复制
const p4 = p3;
可以看到,我们只是将地址复制了一遍,p4 和 p3 都是指向同一个地址,这就说明对
p4
进行修改时就会影响到p3
的值。所以对引用类型进行复制时,应该把堆内存中的内容复制一遍,在将新地址赋值给新变量,这就涉及到深拷贝了, 那我就简单的实现下深拷贝:
深拷贝
// 第一种
const a = {};
const b = JSON.parse(JSON.stringfy(a));
// 第二种
function clone(obj, hash = new WeakMap()) {
// 判断是否为 null 或者 typeof 返回类型是否为 object
if (obj == null || typeof obj !== "object") return obj;
else if (obj instanceof Date) return new Date(obj);
else if (obj instanceof RegExp) return new RegExp(obj);
// 判断集合是否有这个属性,有则直接 return obj
if(hash.has(obj)) return hash.get(obj)
const newObj = new obj.constructor();
// 将属性和拷贝后的值作为一个map
hash.set(obj, newObj);
// 遍历 obj
for (let key in Object.getOwnPropertyDescriptors(obj)) {
// 过滤掉原型身上的属性
if (obj.hasOwnProperty(key)) {
// 递归拷贝
newObj[key] = clone(obj[key], hash);
}
}
return newObj;
}
堆总结
堆内存的特点:使用灵活,可以动态增加或删除空间,但是存取比较慢
更多推荐
所有评论(0)