我们常常会听说什么栈内存、堆内存,那么他们到底有什么区别呢,在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. zencart清空产品商品实用命令

    TRUNCATE TABLE categories; TRUNCATE TABLE categories_description;TRUNCATE TABLE meta_tags_categories ...

  2. 1024·程序员节来啦!MyEclipse致敬改变世界的程序猿

    1024·程序员狂欢季 MyEclipse/CodeMix — Java开发利器!现金红包免费领! 快拆开看你的最大优惠券是多少,幸运奖红包翻倍!   (活动期间在线下单的客户才可享受此优惠,过期恢复 ...

  3. python脚本打包成exe可执行文件

    1. 工具pyinstaller (pip install pyinstaller) 2.生成exe (pyinstaller -F -w Capturing_PDFs.py) 参数 -F 生成单个文 ...

  4. 汇编call jmp理解

    CALL   指令在实现转移之前,   要将返回地址存入堆栈的,   以便子程可以通过   ret   指令返回到   CALL   指令下面的指令接着运行;   jmp   就没用这些事儿,   直 ...

  5. zabbix自动注册,实现自动添加机器,减少人工干预

    1.zabbix_agent的安装配置: vim install_zabbix_agent.sh #!/bin/bash #author:chenjianwen RealIP=`curl -s htt ...

  6. Linux可变参数打印日志(二)

    #include<stdio.h> #include<stdlib.h> #include<stdarg.h> #include<string.h> # ...

  7. XOR Guessing

    ​ E. XOR Guessing 第一次做这种交互题,刚开始还看不懂,现在已经差不多可以理解了,清空缓存区用cout<<endl;即可,需要注意的是,如果用fflush(stdout)来 ...

  8. JavaWeb-SpringSecurity自定义登陆配置

    系列博文 项目已上传至guthub 传送门 JavaWeb-SpringSecurity初认识 传送门 JavaWeb-SpringSecurity在数据库中查询登陆用户 传送门 JavaWeb-Sp ...

  9. Zabbix 4.0.2试用(七):在Linux主机中安装zabbix agent并添加该主机(yum源安装)

    Zabbix 4.0.2试用(七):在Linux主机中安装zabbix agent并添加主机(yum源安装) 2018年12月20日, 上午6:42 之前介绍的是下载源安装包,编译安装的方式来安装ag ...

  10. Jmeter -- 对并发认识的误区

    1. 误区 如下图所示,并发数设置为1000,启动时间设置1s,就是每秒发起1000个请求(错误) 上述的设置,表示在1s内启动1000个线程,之后,jmeter便以最大限度的1000个并发进行压测, ...