Js中的堆区,栈区

堆栈

定义:
  • 堆区与栈区都是程序运行时内存中分配的一个数据区,用于存放程序中的变量与数据;

  • 二者存储的数据类型和处理速度不同;

  • 栈(stack)中主要存放一些基本类型的变量和对象的引用,(包含池,池存放常量),其优势是存取速度比堆要快,并且栈内的数据可以共享,但缺点是存在栈中的数据大小与生存期必须是确定的,缺乏灵活性;

  • 堆(heap)用于复杂数据类型(引用类型)分配空间,例如数组对象、object对象;它是运行时动态分配内存的,因此存取速度较慢。

基本数据类型:
Undefined、Null、Boolean、String、Number、Symbol都是直接按值直接存在栈中,每种类型的数据占用的内存空间大小都是固定的,并且由系统自动分配自动释放。

引用数据类型:
Object,Array,Function这样的数据存在堆内存中,但是数据指针是存放在栈内存中的,当我们访问引用数据时,先从栈内存中获取指针,通过指针在堆内存中找到数据。

let a = 123445;
let b = "asdasd";
let c = null;
let d = {age:20};
let e;
let f = true;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Fh5QzJFk-1578915203151)(/static/upload/article/1578910200297.png)]

  1. 在定义的数据中,变量a,b,c,e,f,存储的是简单数据类型,所以直接存放。
  2. 变量d定义的是一个对象,对象属于复杂数据类型,会将其真实数据存放在堆区。
  3. 在堆内存中定义变量d,通过指针的方式引用所定义的对象,变量d中存储的是 对象在堆内存中的地址
  4. const定义对象实,也是基于定义指向其在堆内存中的地址,所以const定义对象可以通过 点 操作改变对象中的值,而不能改变定义的简单数据类型的值。
不同:
  1. 申请方式不同。栈由系统自动分配,而堆是人为申请开辟;
  2. 申请大小的不同。栈获得的空间较小,而堆获得的空间较大;
  3. 申请效率的不同。栈由系统自动分配,速度较快,而堆一般速度比较慢;
  4. 底层不同。栈是连续的空间,而堆是不连续的空间。

案例

栈区
 let a = 66;
 let b = a;
 console.log(++a,b+5);
//67 71

结论:堆区中存储的变量,相互赋值,应用不会应用原先的值,他们是相互隔离的

堆区
    let person1 = {
        name:"bob",
        age:18,
        sex:"boy"
    };
    let person2 = person1;
    person2.name = "jack";
    person2.age = "22";
    console.log("person1:",person1);
    console.log("person2:",person1);
    console.log(person1 === person2);//判断两个对象是否全等

结果:
在这里插入图片描述
输出的结果中person1与person2的结果完全相同,全等判断也等于true,而我们操作只是操作了person2对象,理应不会修改person1中的值,但为什么出现了以上情形呢?
原因:
由于栈区,堆区存储数据类型不同,方式也不同,声明person1时的对象实际上是存储在了堆区,而变量person1则声明在栈区,通过指针的形式引用堆区中的对象,所以在为变量person2赋值时,复制的其实是对象的地址,也就是person1,person2所存储的都是堆区变量的同一地址,都是指向同一个对象,导致操作person1或person2实际都是操作的同一对象。
由于堆栈机制的存在,我们在对数据进行拷贝复制时,不能仅使用简单的赋值操作,这也是Js中为什么会存在深拷贝与浅拷贝的原因,下篇文章我们来盘深浅拷贝

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值