最近拿出了很久没看的《JavaScript高级程序设计(第三版)》重温,之前看过的两遍仅仅走马观花没有深入,而且对前面的章节并没有很上心去理解。最近从第一章开始仔细的看内容,并且做好笔记:
https://github.com/chaihongjun/Professional_JS_For_Web_Developers_3rd
上面是本人学习的笔记。目前就遇到的第四章的变量和内存问题反复研究,由于不太清楚引用类型在内存中的存放方式,因此在搞懂参数传递前,先把这方面的困惑解决。
首先可以明确的几个概念:
JS的数据类型分为简单数据类型(基本数据类型)和复杂数据类型(Object)
简单数据类型包含5钟:Undefined,Null,Boolean,Number和String
复杂数据类型就是Object
JS的变量同样分为两种:基本类型和引用类型
5种简单数据类型对应的是基本类型值,存放在栈内存中
Object,Array,Function,Date等对应的是引用类型值,存放在堆内存中。
下面用一张网图来研究:
从这张图可以分析以下几点:
基本类型变量都是存放在栈中,大小是固定的,栈中直接存放的基本类型变量的值
Object的内容存放在堆中,而栈里面存放的只是这个变量的一个内存地址。因为,像对象这些复杂的数据类型它的大小不是固定的,但是内存地址是固定的,因此在栈里存放的是这个变量的“门牌号地址”,通过这个“门牌号地址”可以进一步找到实际的内容(也就是值)。
对于已知大小的变量一定是存放在栈内,而无法确认的一定是放在堆内。
基本类型变量内容带大小固定,可以在栈内找到
引用类型变量,将存放内容在堆内的地址放在了栈里面。
关于JS变量复制的不同
基本类型变量的复制就是我们常规理解的COPY,在栈内开辟一个和原变量大小一样的新空间,然后将原变量的内容复制一份放到这个新的空间内。
引用类型变量的复制相当于"复制门牌号码",首先,引用类型的真实内容是存放在堆内的。复制的时候还是在栈内开辟新的空间,新的内存空间存放的不是原变量的真实内容(“家具”),而是原变量的“门牌号”,这里的“门牌号”实际是保存“房间内家具”的堆的内存地址。
函数参数传递的一些困惑:
ECMAScript中所有函数的参数都是按值来传递的。这个目前还没有理解,后续会更新博客来理解。