本文概述
文章主要内容:
- JS内存空间
- JS变量对象
- 执行上下文
JS内存空间
JS中没有严格意义上区分堆内存与栈内存。
- 栈数据结构 栈空间先进后出,后进先出
- 堆数据结构 堆内存是一种树状结构,它的存取数据的方式,则类似于书架与书。
- 队列 先进先出的数据结构。
执行上下文详解
1. 概念:
每当控制器转到可执行代码的时候,就会进入一个执行上下文,执行上下文可以理解为当前代码的执行的环境,它会形成一个作用域。 javascript的运行环境一般分为以下这些情况:
- 全局环境 javascript代码运行起来会首先进入该环境
- 函数环境 当函数被调用执行,会进入当前函数中执行代码 因此在一个javascript程序中,必定会产生多个执行上下文,javascript引擎会以栈的形式来处理它们,这个栈称其为 函数调用栈。栈底永远都是全局上下文,而栈顶是当前正在执行的上下文。
处于栈顶的上下文执行完毕后会自动出栈。全局上下文会在浏览器关闭后出栈。 函数中,遇到return能直接终止可执行代码的执行,因此会直接将当前上下文弹出栈。
特点:
- 单线程
- 同步执行,只有栈顶的上下文处于执行中,其他上下文需要等待
- 全局上下文有且只有一个,它在浏览器关闭后出栈
- 函数的执行上下文没有个数限制
- 每次某个函数被调用,就会有个新的执行上下文被调用,即使是调用的是自身函数,也是如此。
变量对象
javascript的执行上下文生成之后,会创建一个叫做的变量对象的特殊对象,js的基础数据类型往往都会保存在变量对象中。
严格意义上来说,变量对象也是存放在堆内存中,但是由于变量对象的特殊职能,在理解时仍然需要将其于堆内存中区分开来。
基础类型都是一些简单的数据段,是按值访问的,因此可以直接操作保存在变量中的内存值。 引用数据类型,它们值的大小是不固定的,引用数据类型的值是保存在堆内存中的对象,js不允许直接访问堆内存中的位置,因此不能直接操作对象的内存空间。在操作对象时,实际上是在操作对象的引用而非实际的对象。因此引用类型的值都是按引用访问的,这里的引用,可以理解为保存在变量对象中的一个地址,该地址与堆内存中的实际值相关联。
内存空间管理
因为js有自动垃圾收集机制,内存的分配和回收都实现了自动管理。但是了解内存机制有助于清晰的认识到自己写的代码在执行过程中发生过什么,从而写出性能更优越的代码。
JS的内存生命周期:
- 分配你所需要的内存
- 使用内存
- 在不需要时将其释放,归还
回收机制
在js中最常用的是通过标记清除的算法来找到哪些对象是不再继续使用的,因此a=null其实仅仅只是做了一个释放引用的操作,让a原来对应的值失去引用,脱离执行环境,这个值会在下一次垃圾收集器执行操作时被找到并释放。