JavaScript之内存空间

 开发中,声明变量是每个前端都经常做的一件事,那么你声明的变量都是怎么存放的呢?

开发中的变量按数据类型分为

基本数据类型(Undefined、Null、Number、String、Boolean和Symbol)

引用数据类型(Object)

浏览器内存空间中有栈和堆,其中

存放基本数据类型以及引用数据类型的内存地址

存放引用数据类型

下面我们用图更加形象的解释一下栈和堆:


可以看到,当查找引用数据类型的时候,先在栈中找到它的内存地址,然后通过内存地址找到堆中的Object(可能这就是叫做引用数据类型的原因吧)

计算机对栈的读取要比堆快,而且栈中每个变量占有固定大小的空间,而Object的大小是变化的(可以对其进行增删改查操作),所以Object放在堆中,但是栈中存放有它对应的内存地址,通过这种方式实现引入数据类型的读取和操作。

可能代码+图会更加好理解:

let a = 1,b = 'str',c = {name:'c'},d = false;复制代码


接下来我们看几个例子:

let a = 1;
let b = a;
a = 2;
a // 2
b // 1复制代码

let a = 1,在内存中开辟a的内存1

let b=a,在内存中开辟b的内存1

a = 2,将a内存中的值修改为2

let obj1 = {name:'obj1'};
let obj2 = obj1;
obj1.name = 'obj2';
obj1 // {name:'obj2'}
obj2 // {name:'obj2'}复制代码

let obj1 = {name:'obj1'},在堆中保存对象 {name:'obj1'},并将变量obj1指向该对象的内存地址

let obj2 = obj1,在栈中创建obj2的空间,并将其指向{name:'obj1'}的内存地址

obj1.name = 'obj2',通过obj1对{name:'obj1'}的引用,修改其name为obj2,所以该对象变为{name:'obj2'}

总结:(源自高程3)

如果从一个变量向另一个变量复制基本类型的值,会在变量对象上创建一个新值,然后把该值复制 到为新变量分配的位置
当从一个变量向另一个变量复制引用类型的值时,同样也会将存储在变量对象中的值复制一份放到 为新变量分配的空间中。不同的是,这个值的副本实际上是一个指针,而这个指针指向存储在堆中的一 个对象。复制操作结束后,两个变量实际上将引用同一个对象。因此,改变其中一个变量,就会影响另 一个变量

既然说到内存,我们就再谈一下浏览器内存空间的管理,如上所述

当声明一个变量的时候,如果为基本数据类型,浏览器会为其在栈中分配内存空间,如果为引用数据类型,浏览器会为该变量在栈中分配内存空间,同时将其声明的Object存放在堆中,并将该变量指向Object的内存地址

接下来是该变量的使用过程(读,写)

如果该变量不再被使用,则将其释放,浏览器的垃圾回

而JavaScript 中最常用的垃圾收集方式是标记清除

当变量进入环境的时候(如:变量被声明),将其标记为‘进入环境’,而当该变量不再需要的时候,则将其标记为‘离开环境’。每隔一段时间,浏览器的垃圾收集器就会运行一次,将标记为‘离开环境’的变量回收,并释放其内存。

注:以上为了方便理解对垃圾回收机制做了简化,有兴趣的朋友可以自行查阅高程 4.3

如果有错误或者不严谨的地方,请给予指正,十分感谢!


转载于:https://juejin.im/post/5c948bac6fb9a070e82c13aa

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值