js的内存
在JS中,每一个数据都需要一个内存空间,内存空间又分为栈内存(stack)与堆内存(heap)和池。池存放常量,所以也叫常量池,一般归类于栈中。
栈的数据结构
栈是一种特殊的列表,栈内的元素只能通过列表的一端访问,这一端称为栈顶。 栈被称为是一种后入先出(LIFO,last-in-first-out)的数据结构
如图,处于盒子中最顶层球 4,它一定是最后被放进去,但可以最先被使用。 而我们想要使用底层的乒乓球 1,就必须将上面的 3 个球取出来,让球1处于盒子顶层。 这就是栈空间先进后出,后进先出的特点。
堆的数据结构
堆是一种经过排序的树形数据结构,每个结点都有一个值。通常我们所说的堆的数据结构,是指二叉堆。堆的特点是根结点的值最小(或最大),且根结点的两个子树也是一个堆。由于堆的这个特性,常用来实现优先队列,堆的存取是随意的,这就如同我们在图书馆的书架上取书,虽然书的摆放是有顺序的,但是我们想取任意一本时不必像栈一样,先取出前面所有的书,我们只需要关心书的名字。
栈内存一般存储原始类型数据
Number String Null Undefined Boolean Symbol
例如:
let num = 1;
我们定义一个变量num,系统自动分配存储空间。我们可以直接操作保存在栈内存空间的值,因此基础数据类型都是按值访问。数据在栈内存中的存储与使用方式类似于数据结构中的堆栈数据结构,遵循 后进先出的原则。
堆内存一般储存引用数据类型
例如:
let people = {
name:'zhangsan',
age:18
}
let arr = [1,2,3]
JS的引用数据类型,比如数组Array,它们值的大小是不固定的。引用数据类型的值是通过 v8 引擎的 map 机制 保存在堆内存中的对象。JavaScript不允许直接访问堆内存中的位置,因此我们不能直接操作对象的堆内存空间。
我们要访问堆内存中的引用数据类型时,实际上我们首先是从栈中获取了该对象的指针,然后再从堆内存中取得我们需要的数据。
所以,我们经常说:基本类型赋值相互不影响,引用类型赋值,会影响原对象。
例如:
let num = 1;
let num1 = num;
num1 = 2;
console.log(num,num1) // 1 2 值互不影响
let people = {
name:'zhangsan',
age:18
}
let other = people;
other.age = 20;
console.log(people,other); // {name: 'zhangsan', age: 20} {name: 'zhangsan', age: 20} 影响了原对象