前端基础系列(四) -- 内存
概述
电脑开机之后就把硬盘中的数据传输到内存中,例如操作系统,把硬盘中的操作系统读到内存中即是开机。内存特点是:存储数据快,一旦断电,数据就丢失了。与内存相对应的是外存,表示无论断电与否,数据都存在,外存的存储速度慢。
示例
Chrome 浏览器打开之后大约占用了 1G 的内存,分别分配给每个页面,每个页面大约占用 100M ,其中包括了:
1. HTML + CSS
2. JavaScript
3. 网络 HTTP
4. 其他
所以 JavaScript 最多占用约 100M 的内存。
内存分类
JS 将内存划分为两个大区,分别是代码区(存储代码)和数据区(存储数据)1
let a = 1 // 变量 a 存储在代码区 数字 1 存储在数据区 二者以 JS 引擎关联
数据区
数据区分为 Stack(栈内存) 和 Heap(堆内存)。
Stack(栈内存)存储方式是以一行一行存储,类似栈,故而叫做栈内存
Heap(堆内存)存储方式是以堆存储
存储
- 数字是以 64 位浮点数进行存储
- 字符是以 16 位的进行存储。
存储
var a = 1
时,a 在代码区,1 以64位浮点数存储在栈内存。存储
var b = 2
时,b 在代码区,2 以64位浮点数存储在栈内存。
注意:当 b = a
时,将 a 中的数据复制并覆盖到 b 的数据上。
存储
var a = true
时,a 在代码区,true 转化为 1 ,之后以64位浮点数存储在栈内存。存储
var obj1 = {}
时,obj1 在代码区,在栈内存中会存有一个以64位浮点数的地址,引用的是堆内存中的一个地址,obj1 中的数据将存储在堆内存中的一个地址,如果在后面在 添加 obj1 的属性 ,继续放在堆内存中。存储
var obj2 = {}
时,obj2 在代码区,在栈内存中会存有一个以64位浮点数的地址,引用的是堆内存中的一个地址,obj2 中的数据将存储在堆内存中的一个地址。
注意:当 obj2 = obj1
时,和 b = a
做的事情完全相同,即将 obj1 中的数据地址复制并覆盖到 obj2 的数据地址上。
数据类型存储方法:
JavaScript 中有 7 种数据类型
简单数据类型(6种)直接存储在 Stack(栈内存)中
复杂数据类型(Object)在 Stack(栈内存)中存储 Heap(堆内存)的地址
所有的变量和对象的关系都是引用关系。
套路:
1 | var a = { n: 1 }; |
基本概念
垃圾回收
如果一个对象没有被引用,就是垃圾,将会被回收(释放内存)。
内存泄露
由于浏览器的 BUG ,使得应该被标记为垃圾的东西,没有被标记为垃圾,造成内存被永久占用,除非把浏览器关闭。
解决方法:在关闭页面之前把所有的事件设置为 null 。
浅拷贝&深拷贝
基本数据类型
1 | var a = 1; |
对于基本类型,所有的赋值 “ = “ 都是深拷贝
所以在谈及深拷贝和浅拷贝时是不考虑基本类型的,因为基本类型的赋值都是深拷贝
复杂数据类型(Object)
浅拷贝:1
2
3
4var a = { name : 'a' };
var b = a;
b.name = 'b' ; // b 变致 a 变,即是浅拷贝
alert( a.name ); // 'b'
深拷贝:b 复制 a 的所有数据,但是地址不同,最终的结果就是 b 变是 b 自己的事情,与 a 无关,即 b 变不影响 a