一、JS的数据类型分类:
前面的文章,我们提到过,JS数据类型,分为基本数据类型和引用数据类型
其中,基本数据类型:直接在栈内存中保存数据值,按值访问,变量与变量之间独立存在,其中一个修改不会影响其他值 【按值访问的变量复制“你的就是你的,我的就是我的,咱们都有副本,互不影响。”】;数据比较时:比较数值大小;
引用数据类型:变量在堆内存中保存的是内存地址,访问时访问的是内存的地址(指针),当两个变量引用的是同一个数据对象,一个改变,另一个也会改变; 比较的是保存数据的内存地址。按引用访问的变量复制是变量的指针,注意,是指针,指向的还是同一个值
为什么要实现两种存储方式的理由很简单?
就是基本类型一旦初始化则内存大小固定,访问变量就是访问变量的内存上实际的数据,称之为按值访问。
而对象类型说不定什么时候就会增加自身的大小,内存大小不固定。比如动态添加对象的属性、动态增加数组的大小等等都会使变量大小增加,无法在栈中维护。所以js就把对象类型的变量放到堆中,让解释器为其按需分配内存,而通过对象的引用指针对其进行访问,因为对象在堆中的内存地址大小是固定的,因此可以将内存地址保存在栈内存的引用中。这种方式称之为按引用访问。
*栈内存中存放基本类型变量,以及对象的指针;堆中存放对象实体
二、堆和栈是什么?
栈:主要表现为一种数据结构,是只能在某一端插入和删除的特殊线性表。它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读取数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。
栈是允许在同一端进行插入和删除操作的特殊线性表。允许进行插入和删除操作的一段成为栈顶,另一端称为栈底;栈底固定,而栈顶浮动 ;栈中元素个数为零时,称为空栈。插入一般称为进栈(PUSH),删除则称为退栈(POP)。栈也称为后进先出表。
如图所示:
堆:
在程序中,堆用于动态分配和释放程序所使用的对象。在以下情况中调用堆操作:
1.事先不知道程序所需对象的数量和大小。
2.对象太大,不适合使用堆栈分配器。
堆使用运行期间分配给代码和堆栈以外的部分内存。
在javascript中,引用数据是放在堆中的,例如数组和对象,因为在javascript中,一切都是对象,对象可以进行扩展,放置在堆中可以进行不断的扩展,如果放在内存中就会消耗大量资源。放置在堆中的数据的查询效率比较低。这也是内存优于堆的好处,但是内存的存储空间要比堆的小很多。
按引用访问,当查询时,需要先从栈中读取内存地址,然后再顺藤摸瓜找到保存在堆内存中的值
栈的优势就是存取速度比堆要快,仅次于直接位于CPU中的寄存器,但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,垃圾收集器会自动地收走这些不再使用的数据,但是缺点是由于在运行时动态分配内存,所以存取速度较慢。
所以相对于简单数据类型而言,他们占用内存比较小,如果放在堆中,查找会浪费很多时间,而把堆中的数据放入栈中也会影响栈的效率。比如对象和数组是可以无限拓展的,正好放在可以动态分配大小的堆中。
————————————————
版权声明:本文为CSDN博主「hhthwx」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/hhthwx/article/details/78146169 && https://www.php.cn/js-tutorial-340047.html