基础数据类型存放在栈中,引用数据类型存放在堆

为什么基础数据类型存放在栈中,而引用数据类型存放在堆中?_引用数据类型存储在栈中_啥也不会的毛不会的博客-CSDN博客

目录

栈:

堆:

js的执行栈:

基本数据类型和引用数据类型的区别:

为何基本数据类型存放在栈中?

为何引用数据类型存放在堆中?

最后,闭包:

  • 栈:原始数据类型(Undefined、Null、Boolean、Number、String)
  • 堆:引用数据类型(对象、数组和函数)

栈:


        栈的特点是:出口跟入口是同一个,遵循着先进后出、后进先出的原则数据只能顺序的入栈、顺序的出栈。 这也是我们学到的有关栈这一数据结构最重要的一个特性了,但是除此之外,栈还有着能直接存到底层寄存器,存取效率高、固定空间大小等特点。

堆:

        堆的特点是无序的key-value键值对存储方式。堆的存取方式跟顺序没有关系,不会局限于出入口。

js的执行栈


        执行栈又被称为执行上下文栈或调用栈。

        程序执行进入一个执行环境时(比如整个script标签或进入一个函数内部),它的执行上下文就会被创建,执行上下文包含了函数的参数和局部变量,并被推入执行栈中(入栈);程序执行完成后,它的执行上下文就会被销毁,并从栈顶被推出(出栈),继续执行下一个执行上下文。

        因为JS执行中最先进入全局环境,所以最开始处于栈底的是全局环境的执行上下文。而处于栈顶的是当前正在执行函数的执行上下文,当函数调用完成后,它就会从栈顶被推出。

        我们所说的基本数据类型存放于栈中,说的也是执行栈的这个栈。

        而js在执行的时候,就是将js代码从上到下遍历、然后不断的将事件及变量推入执行栈又不断从栈顶抛出的过程。

基本数据类型和引用数据类型的区别:


基本类型
        占用空间固定,保存在栈中

        保存与复制的是值本身

        可以使用typeof检测数据的类型

引用类型
        占用空间不固定,保存在堆中

        保存与复制的是指向对象的一个指针(浅拷贝)

        使用instanceof检测数据类型

        使用new()方法构造出的对象是引用型

为何基本数据类型存放在栈中?


        在js中,基本数据类型变量大小固定,并且操作简单容易,所以将其放入栈中存储。

        基础数据类型的内存大小是固定的。就算是看似可以无限伸长的String字符串,也是有边界的,Number所能够表达的数值范围也限定于Number.MIN_VALUE到Number.MAX_VALUE之间,Boolean和Symbol类型就更小了。

        而栈内存,恰好也是固定空间大小的。不仅是栈结构的每一项元素大小,而且整个栈结构的整体大小都是固定大小的,如果存放东西过多,就会栈溢出。

        固定的内存空间位置意味着查找效率也会进一步提升。因为内存空间位置固定下来后,不必再一点点遍历查看这个对象是否结束,是否到了下一个对象,而是可以直接跳到下一个对象。

为何引用数据类型存放在堆中?


        引用数据类型的大小是不固定的,如数组可以无限扩充,对象可以自由添加属性。将他们放在堆中是为了不影响栈的效率。而是通过引用的方式查找到堆中的实际对象再进行操作。

最后,闭包:


        说到这里,大家应该也差不多明白为何基本数据类型存放在栈中,引用数据类型存放在堆中了。但是事实上,并非所有情况都如此。当我们使用了闭包的时候,JavaScript 引擎会沿着“当前执行上下文–>foo 函数闭包–> 全局执行上下文”的顺序来查找变量,而这一变量(不管是基本数据类型还是引用数据类型)也会被存到[[scope]]中,然后将其放到堆内存里面去。这也是可以理解的,就跟为什么引用数据要存放到堆中一样,是为了避免这些存储的数据在栈中影响到执行栈的执行,为了让js更加的高效。


 

你可能感兴趣的:(javascript,java,开发语言)