我们常常会听说什么栈内存、堆内存,那么他们到底有什么区别呢,在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. kotlin函数和函数式表达式

    这次的写法可能有些怪异,但是如果熟悉java8的Lambda表达式的话其实理解起来很顺其自然[参考博客:http://www.cnblogs.com/webor2006/p/7705130.html] ...

  2. Springboot + Mybatis + Ehcache

    最近在做一个项目,为处理并发性较差的问题,使用了Mybatis二级缓存 但在多表联合查询的情况下,Mybatis二级缓存是存在着数据脏读的问题的 两天就是在想办法解决这个数据脏读的问题 考虑到简易性. ...

  3. Java-20180412

    今天开始重新复习Java,完成了leetcode的第一题. 1.算法: 给定一个数组和目标值,找出相加等于目标值的数组元素的下标. 数组[2,7,11,15]; target:9; 返回:[0,1]; ...

  4. 下载Mybatis源码

    百度搜索关键字:Mybatis 点击第二个选项,为啥不是第一个?因为卡. 打开之后,长这个样子: 点击画红圈的位置,进入github源码库: 发现,进入的太深了.点击mybatis-3,进到外层目录, ...

  5. New!Devexpress WPF各版本支持VS和SQL Server版本对应图

    点击获取DevExpress v19.2.3完整版试用下载 本文主要为大家介绍DevExpress WPF各大版本支持的VS版本和支持的.Net版本图,Devexpress WPF v19.2.3日前 ...

  6. Python 判断文件是否存在,不存在则将名称写入指定文件

    import os filename = '15464657761111111.pdf' pathDir = 'F:/tqcs/sr' # 判断文件是否存在 if os.path.exists(pat ...

  7. 设计一个Mypoint类,求两个点之间的距离

    package Test; public class test6 { public static void main(String[] args) { // TODO Auto-generated m ...

  8. List集合、泛型、装箱拆箱

    1.List集合 Vector:增删改查都慢 线程同步 线程安全 LlinkedList:以链表结构存储数据,查询慢.增删快 ArrayList:的运行速度比较快 连续数据空间存储数据,查询快(下标) ...

  9. 【转】vue 手动挂载$mount() 获取 $el

    原文:https://www.cnblogs.com/CyLee/p/8425183.html 手动挂载$mount() 如果没有挂载的话,没有关联的 DOM 元素.是获取不到$el的. https: ...

  10. 51 Nod1042 数字0到9的数量

    1042 数字0-9的数量  基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题  收藏  关注 给出一段区间a-b,统计这个区间内0-9出现的次数. 比如 10-19 ...