阅读 117

V8数据存储(上篇):栈和堆

正文

栈和堆,用于存储数据的两种方式。在深入理解V8中的栈和堆之前,我们先看看语言本身。

JavaScript是什么语言?

通常将语言分为静态语言和动态语言,像C语言这类在使用前需明确定义变量的数据类型,我们称之为静态语言,相反的,像JavaScript在运行过程中需要检查数据类型的,称之为动态语言。

同样的在JavaScript使用过程中,编译器经常偷偷的进行类型转换,比如在 If() 条件语句中,"" 空字符串,会被转化为 false,我们把这种现象称之为:隐式转换。 能进行隐式转换的语言,我们称之为弱类型语言,相反的不支持隐式转换的语言成为强类型语言。

所以,可以看出:JavaScript是动态的、弱类型语言

8种数据类型

JavaScript存在8种数据类型,其中7种为基础数据类型,1种为引用类型,具体如下:

基础数据类型:

Boolean | Number | String | Symbol | BigInt | Null | undefined

引用类型:

Object

这里需要注意的是,typeof null === "object",这是历史遗留的bug。区分不同类型的数据,是因为不同类型的数据存储的位置一样。

顺便提下,因为 Arraytypeof 值也是 object ,所以日常我们判断数组有下面的方式:

// 1
Array.isArray([]).  // true

// 2
Object.prototype.toString.call([]) === "[object Array]"  // true复制代码
栈和堆

一段代码经过编译,会产生一个执行上下文和可执行代码。在执行上下文中又分为变量环境和词法环境,变量环境用于存放当前上下文的变量,词法环境用于解决JavaScript中变量提升的问题,引入了块局作用域。以下面代码为例:

var a = 1
let b = 2
function c(){
   console.log('')
}复制代码

上面代码经过编译后,var a 将被放到变量环境,并赋初值undefinedlet b,会被放到词法环境,注意此处并没有赋予初始值,倘若在未赋初始值便使用该变量,会形成一个暂时性死区,会报错。遇到function c 时,会将函数存储到堆中,同时将函数声明c放到变量环境,赋予函数在堆中的内存地址。

那这里为啥要将函数存在堆中,而不直接放在变量环境呢?

当代码开始执行后,会将当前代码编译后产生的执行上下文放入调用栈中,调用栈作为执行上下文切换的环境,当栈数据量越大,上下文数据销毁、切换需要消耗大量时间,会影响到整个程序的运行效率,因此栈空间一般都不大。也因为栈空间不大,当你疯狂递归执行某块代码,容易造成栈空间溢出。

堆空间用于存储引用类型,比如大对象,函数等等,会在分配存储空间、以及取数据存在一定的开销。

通过存储整个过程,我们可以得知,存在3中存储类型:栈、堆,以及代码空间。栈用于存储简单的基本数据类型,堆存储引用类型这些潜在的大数据对象。

涉及到堆和栈的数据存储,必然存在数据回收,也就是浏览器的垃圾回收机制。后面再讲!


作者:梁龙先森
链接:https://juejin.cn/post/7026730754746875941


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐