我们常常会听说什么栈内存、堆内存,那么他们到底有什么区别呢,在js中又是如何区分他们的呢,今天我们来看一下。

一、栈内存和堆内存的区分

一般来说,栈内存主要用于存储各种基本类型的变量,包括Boolean、Number、String、Undefined、Null...以及对象变量的指针,这时候栈内存给人的感觉就像一个线性排列的空间,每个小单元大小基本相等,栈内存中的变量一般都是已知大小或者有范围上限的,算作一种简单存储。

堆内存主要负责像对象Object这种变量类型的存储,堆内存存储的对象类型数据对于大小这方面,一般都是未知的,(所以这大概也是为什么null作为一个object类型的变量却存储在栈内存中的原因)。

来一张图感受一下:

二、测试

Ⅰ.基本数据类型

        /* 基本数据类型 */
var a = ;
var b = ;
console.log(a === b);//true var c = '桔子桑';
var d = '桔子桑';
console.log(c === d);//true

基本数据类型,因为都是存在栈内存中的,以上面的int为例:

var a = 1;变量 a 存在栈内存中,他的值是基本数据类型(int),自然也是在栈内存中,栈内存有没有1?没有那就拿出一块内存存1,这个变量a指向这块值为1的栈内存地址;

var b = 1;同理,变量 b 也是在栈内存中的,但是赋值的时候,发现,栈内存有一块地址存着int型的值1,那么就直接指向这块栈内存了;

所以最终 a === b 是 true;

Ⅱ.new 关键字生成的对象

        /* new关键字 */
var a = new String('桔子桑');
var b = new String('桔子桑');
console.log(a === b);//fasle

new关键字生成的对象都是存在于堆内存中的,上述代码中:

var a = new String('桔子桑');变量 a 存在于栈内存中,他的值是一个指针,这个指针指向堆内存中的一个对象!

附上一段C代码,方便理解

int  a = ;    /* 实际变量的声明 */

int  * ip;            /* 指针变量的声明 */

ip = &a;        /* 在指针变量中存储 变量a 的地址 */

所以我们应该这么理解:

普通变量的值类型是基本数据类型,指向栈内存中的一块地址;

引用类型变量的值是指针,指向堆内存中的一块地址。

Ⅲ.指针的赋值(引用类型)

        /* 指针赋值 */
var a = new String('桔子桑');
var b = a;
console.log(a === b);//true

我们看到,指针型变量 a 的值是一个指针,指向堆内存中一块地址;

然后 又定义了一个变量 b ,他的值等于 a,a 的值是什么?a 的值是一个指针啊,那么变量 b 就等于这个指针,自然也是指向堆内存的那一块地址咯。

图示:

Ⅳ.const关键字

我们知道const关键字用来定义一个常量,

const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。

对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个栈内存地址,因此等同于常量。

但对于复合类型的数据(主要是对象和数组),变量指向的栈内存地址,保存的只是一个栈内存指针,const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制了。

所以,const保证的是栈内存这边变量与其值不能发生改变,所以对于复合类型,指针指向的堆内存中存的数据结构能否改变是左右不了的。

        /* const关键字 */
const a = ;
a = ; const b = {
name:'jack'
};
b.name = 'tom';

对于前者,因为常量 a 和他的值都是在栈内存中的,不能更改,手动修改只会报错:

而对于后者,因为常量 b 的值是一个指针,这个指针由于存在于栈内存,所以他的指向是不能更改的(堆内存地址),但是对应堆内存地址中存的数据结构(存了一个对象)是可以更改的。

js中的堆内存和栈内存的更多相关文章

  1. Java堆空间Vs栈内存

    之前我写了几篇有关Java垃圾收集的文章之后,我收到了很多电子邮件,请求解释Java堆空间,Java栈内存,Java中的内存分配以及它们之间的区别. 您可能在Java,Java EE书籍和教程中看到很 ...

  2. 浅析JS中的堆内存与栈内存

    最近跟着组里的大佬面试碰到这么一个问题, Q:说说var.let.const的区别 A:balabalabalabla... Q:const定义的值能改么? A:你逗我?不能吧 不知道各位看官怎么想? ...

  3. JS中的堆内存与栈内存

    在js引擎中对变量的存储主要有两种位置,堆内存和栈内存. 和java中对内存的处理类似,栈内存主要用于存储各种基本类型的变量,包括Boolean.Number.String.Undefined.Nul ...

  4. 了解 js 堆内存 、栈内存 。

    js中的堆内存与栈内存 在js引擎中对变量的存储主要有两种位置,堆内存和栈内存. 和java中对内存的处理类似,栈内存主要用于存储各种基本类型的变量,包括Boolean.Number.String.U ...

  5. Java中堆内存和栈内存详解2

    Java中堆内存和栈内存详解   Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,ja ...

  6. 浅析JAVA中堆内存与栈内存的区别

    Java把内存划分成两种:一种是栈内存,一种是堆内存. 一.栈内存 存放基本类型的变量,对象的引用和方法调用,遵循先入后出的原则.     栈内存在函数中定义的“一些基本类型的变量和对象的引用变量”都 ...

  7. Java SE之Java中堆内存和栈内存[转/摘]

    [转/摘]1-3Java中堆内存和栈内存 注解:内存(Memory)即 内存储器,主存,其作用是用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器(辅存)交换的数据. Java中把内存分为两种:栈 ...

  8. 熟悉java堆内存和栈内存和mysql的insert语句中含有id的处理

    java的堆内存和栈内存有什么区别呢? 如果mysql数据库表的id是递增的,如果没有插入id,则id自增,如果插入id,则插入什么就显示什么.

  9. JAVA内存管理之堆内存和栈内存

    我们常常做的是将Java内存区域简单的划分为两种:堆内存和栈内存.这种划分比较粗粒度,这种划分是着眼于我们最关注的.与对象内存分配密切相关的两类内存域.其中栈内存指的是虚拟机栈,堆内存指的是java堆 ...

  10. java堆内存和栈内存的处理

    前段时间学习二叉树在处理删除操作的时候遇到一个头疼的问题:删除节点的时候明明已经置null了可树上该节点依旧存在,还必须执行node.father.left = null;才可以删除node节点,寻找 ...

随机推荐

  1. IIS无法启动解决方案

    1.第一步 2.第二步

  2. (九)zabbix监控web应用

    1)web应用监控介绍 使用zabbix自带的web场景可以监控url的状态码,响应时间,url的下载速度,非常的棒 思路:定义模板-->创建应用集--->定义web场景--->定义 ...

  3. Python把多行文本合并

    在引用论文时,往往格式出错,出现非常多行,这样操作非常不方便.这种方法讲多行合并之后,再处理: # 文件空格和回车键处理工具infile = r'C:\Users\SAM\Desktop\新建文本文档 ...

  4. php类知识---try catch

    <?php try { echo "比赛开始"."\n"; ); } catch (Exception $e ) { echo "获取错误信息: ...

  5. vscode安装eslint插件,代码统一自动修复

    ESlint:是用来统一JavaScript代码风格的工具,不包含css.html等. 方法和步骤: 通常情况下vue项目都会添加eslint组件,我们可以查看webpack的配置文件package. ...

  6. 【JZOJ5801】【2018.8.12省选模拟】circular

    题目大意 分析 把环拆开 线段其实就是区间 对于每个区间,向在TA后面并且b_i最小的区间连边, 然后从每个区间(ai,bi)开始,在保证跳到的区间(aj,bj),bj<=ai+m的情况下向后倍 ...

  7. 部署LVS-DR集群

    设置Proxy代理服务器的VIP和DIP [root@proxy ~]# cd /etc/sysconfig/network-scripts [root@proxy network-scripts]# ...

  8. sqoop参数详解

    从RDBMS到HIVE: sqoop import --connect jdbc:oracle:thin:@//192.168.156.111/test--username test --passwo ...

  9. [HNOI2004][bzoj1211] 树的计数(prufer序列)

    1211: [HNOI2004]树的计数 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3432  Solved: 1295[Submit][Stat ...

  10. linux C线程

    一个应用程序可以启动若干个线程: 线程,是程序执行的最小单位: 一般一个最简单的程序最少有一个线程,就是程序本身,也是主函数: 一个线程阻塞不会影响另一个线程: 多线程的进程可以尽可能多的利用系统CP ...