您好,欢迎来到华拓科技网。
搜索
您的当前位置:首页JS中的栈内存、堆内存

JS中的栈内存、堆内存

来源:华拓科技网

浅谈JS中的堆栈

引言:我们都熟知并且常用JS变量的声明以及初始化(赋值),比如一行极其简单的代码var str = '我是字符串',那么这行代码执行的时候发生了什么呢?再比如var obj = {name: 'reslicma'}又发生了什么?他们一样吗?请看正文。

JS中变量的类型

我们先行讨论JS中变量的类型,因为JS中变量的具体存储方式是取决于这个变量的类型的。JS中的变量共有两大类:基本数据类型引用数据类型,我们下文说基本型就是基本数据类型,引用型就是引用数据类型。

基本数据类型(简单数据类型)

JS中的基本型共有五种:string,number,Boolean,undefined,null。分别对应:字符串类型,数字类型,布尔类型,undefined(变量声明未初始化),null(空对象或理解为空指针)。

引用数据类型

JS中的引用型:Array,Function,Object。但是实际上就是一种:Object型,没错,就是对象,毕竟Array,Function也是对象。JS一切皆对象这句话并不为过······

栈内存和堆内存

var str = `我是字符串`,
    num = 1,
    bl = true,
    nu = null,
    un = undefined,
    obj = {
        name: 'reslicma'
    }
复制代码

在内存中就发生了如下图这样的事情:

我们接下来详细的分析它: 首先,我定义的前五个变量都是基本型,那么他们都是存储在 栈内存当中,并且他们存储的就是 值本身,所以说访问基本型变量就能访问得到 。而obj这个变量是个引用型,所以它在栈内存中只保存了一个指针(或者理解为一个地址),比如上图中的这个地址,那么这个地址指向了堆内存中的一块内存空间,这个空间才是真正存储了这个obj对象的内存空间。

理解栈内存和堆内存

我们来说一下栈内存和堆内存具体的区别和联系。

栈内存就像一个线性的、规则的、大小基本固定的、有序的排列起来的一块块内存空间,就像我上图画的那样,每个单元大小固定,规则有序的排列下来,就是栈。所以,在定义一个基本型变量的时候,发生的事情如下:向栈内存申请(注意是申请)一块空间,然后把你声明的变量名和这个变量的具体的值本身压入这个申请好的小空间内。

栈内存和堆内存的优缺点

那么为什么JS要这样区分栈内存和堆内存呢?在JS中,这些基本型变量大小固定,并且操作容易简单,所以把它们放入栈中存储。引用型变量大小不固定,所以把它们分配给堆中,让他们申请空间的时候自己确定大小,这样把它们分开存储能够使得程序运行起来占用的内存最小。

栈内存和堆内存的垃圾回收

我们知道JS是有垃圾回收制的(不详细说),栈内存中基本型一般在它的当前执行环境结束就会被销毁被垃圾回收制回收,而引用类型不会,因为不确定其他的地方是不是还有一些对它的引用,所以引用型只有在所有对它的引用都结束的时候才会被回收掉。

加深理解

案例1:基本型的复制:

var num1 = 1
var num2 = num1
// 修改num1的值
num1 = 2
console.log(num2) // 还是1,不会改变
复制代码

解析具体过程:首先在栈内存中压入一个变量名为num1、值为1的一个变量。然后,第二行代码:赋值操作,先执行赋值运算符右边的式子,所以通过变量名找到了num1的值1,然后把这个值1返回并且赋值给了num2这个变量,所以栈内存中就又压入了一个变量名为num2、值为1的变量,这两个变量的值1相等但不是同一个。所以,改变num1的值就只改变了num1栈内存中的值,对num2没有任何影响。图解:

案例2:引用型的复制:

var obj1 = {name: 'reslicma'}
var obj2 = obj1
obj1.name = '我被修改了'
console.log(obj2.name) // 我被修改了
复制代码

内存图解:

转载于:https://juejin.im/post/5c7157f3e51d45263fac46

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- huatuo6.cn 版权所有 赣ICP备2024042791号-9

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务