执行上下文和执行栈

词法环境 和 变量环境的区别
前者用于存储函数声明和变量(let const)绑定。
后者仅用于存储变量 (var) 绑定

变量提升原因:
在创建阶段,函数声明存储在环境中,在var情况下,变量会被设置为 undefined
而在let和const情况下下,保持未初始化

执行上下文栈和变量对象

https://muyiy.cn/blog/1/1.2.html#%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B

http://47.98.159.95/my_blog/js-base/001.html#_2-%E8%AF%B4%E5%87%BA%E4%B8%8B%E9%9D%A2%E8%BF%90%E8%A1%8C%E7%9A%84%E7%BB%93%E6%9E%9C%EF%BC%8C%E8%A7%A3%E9%87%8A%E5%8E%9F%E5%9B%A0%E3%80%82

内存空间详解

栈: 后进先出 (LIFO)

堆:key => value 类似只需要知道书的名字就可以拿到这本书

队列: 先进先出 (FIFO) 事件循环(event loop)基础结构

调用堆栈 - 图1

调用堆栈 - 图2

基本类型: 在栈内存中。 Undefined Null Boolean NUmber String Symbol

引用类型: 在堆内存中。 在栈内存中存放的只是该对象的访问地址。 当查询引用类型的变量时,先从栈中读取内存地址,然后通过地址找到堆中的值。

问题:

  1. var a = { name: '前端开发' }
  2. var b = a;
  3. a = null; //{ name: '前端开发' }
  4. // 这时b的值是多少

说明:null是基本类型,a=null之后只是把a存储在栈内存中地址改成了基本类型null。并不会影响堆内存中的对象,所以b的值不受影响。

详情解释链接跳转

内存机制

补充:闭包中得变量保存在堆内存中,

垃圾回收
核心思想就是如何判断内存已经不再使用,常用垃圾回收算法有两种

  • 引用计数(现代浏览器不再使用)
  • 标记清除(常用)

内存泄漏识别方法
**

  1. 打开开发者工具,选择 Memory
  2. 在右侧的Select profiling type字段里面勾选 timeline
  3. 点击左上角的录制按钮。
  4. 在页面上进行各种操作,模拟用户的使用情况。
  5. 一段时间后,点击左上角的 stop 按钮,面板上就会显示这段时间的内存占用情况。

常见内存泄漏及如何避免

https://muyiy.cn/blog/1/1.5.html#%E5%9B%9B%E7%A7%8D%E5%B8%B8%E8%A7%81%E7%9A%84js%E5%86%85%E5%AD%98%E6%B3%84%E6%BC%8F

思考题

从内存来看 null 和 undefined 本质的区别是什么?

  • 全局变量

null 将这个变量的指针对象以及值清空
undefined 将这个对象的值清空,但是这个对象依旧存在
js 会回收全局变量为null的对象

  • 对象的属性

null 给这个属性分配了一块空的内存,值为null
undefined 这个值为空值

undefined:值声明了,但是未对齐初始化
null: 特指对象的值未设置