【进阶1-3期】JavaScript深入之内存空间详细图解(转)
这是我在公众号(高级前端进阶)看到的文章,现在做笔记
https://mp.weixin.qq.com/s/x4ZOYysb9XdT1grJbBMVkg
今天介绍的是JS内存空间,了解内存空间中的堆和栈原理对于理解JS闭包、Event Loop等有很大帮助
知识点:某些情况下,调用堆栈中函数调用的数量超出了调用堆栈的实际大小,浏览器会抛出一个错误终止运行。
对于下面的递归就会无限制的执行下去,直到超出调用堆栈的实际大小,这个是浏览器定义的。
function foo() {
foo();
}
foo();

现在正式开始今天的主题,内存空间详解
栈数据结构
栈的结构就是后进先出(LIFO),如果读过前面两篇文章应该是相当熟悉了。文中使用乒乓球盒子的结构来解释。
处于盒子中最顶层的乒乓球5,它一定是最后被放进去,但可以最先被使用。而我们想要使用底层的乒乓球1,就必须将上面的4个乒乓球取出来,让乒乓球1处于盒子顶层。

堆数据结构
堆数据结构是一种树状结构。它的存取数据的方式与书架和书非常相似。我们只需要知道书的名字就可以直接取出书了,并不需要把上面的书取出来。JSON格式的数据中,我们存储的key-value可以是无序的,因为顺序的不同并不影响我们的使用,我们只需要关心书的名字。
队列
队列是一种先进先出(FIFO)的数据结构,这是事件循环(Event Loop)的基础结构,事件循环我们会在第8期详解介绍。

变量的存放
首先我们应该知道内存中有栈和堆,那么变量应该存放在哪里呢,堆?栈?
1、基本类型 --> 保存在栈内存中,因为这些类型在内存中分别占有固定大小的空间,通过按值来访问。基本类型一共有6种:Undefined、Null、Boolean、Number 、String和Symbol
2、引用类型 --> 保存在堆内存中,因为这种值的大小不固定,因此不能把它们保存到栈内存中,但内存地址大小的固定的,因此在栈中保存该对象的访问地址,值保存在堆内存中。当查询引用类型的变量时, 先从栈中读取内存地址, 然后再通过地址找到堆中的值。对于这种,我们把它叫做按引用访问。

在计算机的数据结构中,栈比堆的运算速度快,Object是一个复杂的结构且可以扩展:数组可扩充,对象可添加属性,都可以增删改查。将他们放在堆中是为了不影响栈的效率。而是通过引用的方式查找到堆中的实际对象再进行操作。所以查找引用类型值的时候先去栈查找再去堆查找。
几个问题
问题1:
var a = 20;
var b = a;
b = 30; // 这时a的值是多少?
问题2:
var a = { name: '前端开发' }
var b = a;
b.name = '进阶';
// 这时a.name的值是多少
问题3:
var a = { name: '前端开发' }
var b = a;
a = null;
// 这时b的值是多少
现在来解答一下,三个问题的答案分别是20、‘进阶’、{ name: '前端开发' }
对于问题1,a、b都是基本类型,它们的值是存储在栈中的,a、b分别有各自独立的栈空间,所以修改了b的值以后,a的值并不会发生变化。
对于问题2,a、b都是引用类型,栈内存中存放地址指向堆内存中的对象,引用类型的复制会为新的变量自动分配一个新的值保存在变量对象中,但只是引用类型的一个地址指针而已,实际指向的是同一个对象,所以修改
b.name的值后,相应的a.name也就发生了改变。对于问题3,首先要说明的是
null是基本类型,a = null之后只是把a存储在栈内存中地址改变成了基本类型null,并不会影响堆内存中的对象,所以b的值不受影响。
内存空间管理
JavaScript的内存生命周期是
1、分配你所需要的内存
2、使用分配到的内存(读、写)
3、不需要时将其释放、归还
JavaScript有自动垃圾收集机制,最常用的是通过标记清除的算法来找到哪些对象是不再继续使用的,使用a = null其实仅仅只是做了一个释放引用的操作,让 a 原本对应的值失去引用,脱离执行环境,这个值会在下一次垃圾收集器执行操作时被找到并释放。
在局部作用域中,当函数执行完毕,局部变量也就没有存在的必要了,因此垃圾收集器很容易做出判断并回收。但是全局变量什么时候需要自动释放内存空间则很难判断,因此在开发中,需要尽量避免使用全局变量。
思考题
var a = {n: 1};
var b = a;
a.x = a = {n: 2};
a.x // 这时 a.x 的值是多少
b.x // 这时 b.x 的值是多少
简答:
(1)、优先级。.的优先级大于=,所以先执行a.x,堆内存中的{n: 1}就会变成{n: 1, x: undefined},改变之后相应的b.x也变化了,因为指向的是同一个对象。
(2)、赋值操作是从右到左,所以先执行a = {n: 2},a的引用就被改变了,然后这个返回值又赋值给了a.x,需要注意的是这时候a.x是第一步中的{n: 1, x: undefined}那个对象,其实就是b.x,相当于b.x = {n: 2}

【进阶1-3期】JavaScript深入之内存空间详细图解(转)的更多相关文章
- JS内存空间详细图解
JS内存空间详细图解 变量对象与堆内存 var a = 20; var b = 'abc'; var c = true; var d = { m: 20 } 因为JavaScript具有自动垃圾回收机 ...
- 前端高质量知识(一)-JS内存空间详细图解
变量对象与堆内存 var a = 20; var b = 'abc'; var c = true; var d = { m: 20 } 因为JavaScript具有自动垃圾回收机制,所 ...
- js内存空间详细图解-笔记
原文参考http://mp.weixin.qq.com/s/NGqdjhoU3MR9LD0yH6tKIw 栈-先进后出堆-类比成书于书架(形象),只要知道Key就可以找到value 基础数据类型(Un ...
- 正则表达式andJS内存空间详细图解
http://www.runoob.com/js/js-regexp.html https://blog.csdn.net/pingfan592/article/details/55189622
- JS进阶之---基本数据类型,引用类型,内存空间
一.内存空间: 为了便于理解,我们暂且先将Js的内存分为栈内存和堆内存. JavaScript具有垃圾自动回收机制,内存的分配与回收都完全实现了自动管理.所以我们在开发时一般会忽视内存空间的问题.但是 ...
- javascript - 内存空间
也许很多人像我一样,觉得JS有垃圾回收机制,内存就可以不管了,以至于在全局作用域下定义了很多变量,自以为JS会自动回收,直到最近,看了阮一峰老师,关于javascript内存泄漏的文章时,才发现自己写 ...
- JS进阶系列之内存空间
也许很多人像我一样,觉得JS有垃圾回收机制,内存就可以不管了,以至于在全局作用域下定义了很多变量,自以为JS会自动回收,直到最近,看了阮一峰老师,关于javascript内存泄漏的文章时,才发现自己写 ...
- javascript中的内存管理
目录 简介 内存生命周期 JS中的垃圾回收器 引用计数垃圾回收算法 Mark-and-sweep回收算法 调试内存问题 闭包Closures中的内存泄露 javascript中的内存管理 简介 在c语 ...
- JavaScript 中对内存的一些了解
在使用JavaScript进行开发的过程中,了解JavaScript内存机制有助于开发人员能够清晰的认识到自己写的代码在执行的过程中发生过什么,也能够提高项目的代码质量.其实关于内存的文章也有很多,写 ...
随机推荐
- Maven的日常
强烈建议把 Maven 的 settings.xml 文件同时放在:%USER_HOME%/.m2/settings.xml 和${maven.home}/conf/settings.xml 两个地方 ...
- Git学习一:基本用法
git config:配置相关信息 git clone:复制仓库 git init:初始化仓库 git add:添加更新内容到索引中 git diff:比较内容 git status:获取当前项目状况 ...
- blender 操作快捷键
选择:a: 全选OR取消选择b: 矩形选择c: 画刷选择ctrl+左键:套索选择ctrl+alt+右键 : 环边选择ctrl+右键:ctrl+tab:切换 点,线,面 选择模式ctrl+- 选择/收缩 ...
- jQuery.extend 函数使用
JQuery的extend扩展方法: Jquery的扩展方法extend是我们在写插件的过程中常用的方法,该方法有一些重载原型,在此,我们一起去了解了解. 一.Jquery的扩展方 ...
- MySql数据库学习笔记(3)
查看默认事务隔离级别 mysql> select @@tx_isolation; mysql> select @@global.tx_isolation; mysql> select ...
- <c:out>标签中的escapeXML属性
<c:out>标签中的escapeXML属性 在<c:out>中,escapeXML属性默认为true. 当设置escapeXML的属性为true时,将value中的值以字符串 ...
- 编写blog第一天
今天玩的比较嗨,离开学还剩半个月了,之前在网上搜集了一些blog制作方面的资料,并且在博客园注册了一个账号,今天才打开了申请已久的blog,现在已经对blog具有的基本功能和界面布局有了比较全面的掌握 ...
- proxysql 系列 ~ 读写分离核心功能
一 相关表介绍 1 mysql_user 列表配置 1 username && password 账号密码 2 default_hostgroup 默认的组ID2 mysq ...
- vue 学习笔记—axios(替代vue-resource)
一.使用 1. 引入CDN的方式 https://unpkg.com/axios@0.16.2/dist/axios.min.js 或者 npm方式 npm install axios --sa ...
- 在maven项目中引用ueditor报错问题
遇到的问题:将pom.xml中引入 <dependency> <groupId>com.baidu</groupId> <artifactId>uedi ...