chaihongjun.me

javascript中变量是放在堆内存还是栈内存

最近拿出了很久没看的《JavaScript高级程序设计(第三版)》重温,之前看过的两遍仅仅走马观花没有深入,而且对前面的章节并没有很上心去理解。最近从第一章开始仔细的看内容,并且做好笔记:

https://github.com/chaihongjun/Professional_JS_For_Web_Developers_3rd

上面是本人学习的笔记。目前就遇到的第四章的变量和内存问题反复研究,由于不太清楚引用类型在内存中的存放方式,因此在搞懂参数传递前,先把这方面的困惑解决。

首先可以明确的几个概念:

  1. JS的数据类型分为简单数据类型(基本数据类型)和复杂数据类型(Object)

  2. 简单数据类型包含5钟:Undefined,Null,Boolean,Number和String

  3. 复杂数据类型就是Object

  4. JS的变量同样分为两种:基本类型和引用类型

  5. 5种简单数据类型对应的是基本类型值,存放在栈内存中

  6. Object,Array,Function,Date等对应的是引用类型值,存放在堆内存中。

下面用一张网图来研究:

694344-20151118170509546-5433197.png

从这张图可以分析以下几点:

  1. 基本类型变量都是存放在栈中,大小是固定的,栈中直接存放的基本类型变量的值

  2. Object的内容存放在堆中,而栈里面存放的只是这个变量的一个内存地址。因为,像对象这些复杂的数据类型它的大小不是固定的,但是内存地址是固定的,因此在栈里存放的是这个变量的“门牌号地址”,通过这个“门牌号地址”可以进一步找到实际的内容(也就是值)。

  3. 对于已知大小的变量一定是存放在栈内,而无法确认的一定是放在堆内。

  4. 基本类型变量内容带大小固定,可以在栈内找到

  5. 引用类型变量,将存放内容在堆内的地址放在了栈里面。

关于JS变量复制的不同

  1. 基本类型变量的复制就是我们常规理解的COPY,在栈内开辟一个和原变量大小一样的新空间,然后将原变量的内容复制一份放到这个新的空间内。

  2. 引用类型变量的复制相当于"复制门牌号码",首先,引用类型的真实内容是存放在堆内的。复制的时候还是在栈内开辟新的空间,新的内存空间存放的不是原变量的真实内容(“家具”),而是原变量的“门牌号”,这里的“门牌号”实际是保存“房间内家具”的堆的内存地址。

函数参数传递的一些困惑:

ECMAScript中所有函数的参数都是按值来传递的。这个目前还没有理解,后续会更新博客来理解。

知识共享许可协议本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。作者:柴宏俊»