由于javascript有GC存在,因此内存空间并非被咱们重视。王立大神说"理解内存空间,就是成为大牛的开始"。因此咱们颇有必要学习和理解内存空间。javascript
最新的ECMAScript标准定义了7中数据类型,其中就包括6中基本数据与一种引用数据类型(object)前端
其中基础数据类型如图所示:java
下面来探讨一个问题,有一个很简单的例子以下所示:面试
function fn() {
var a1 = 10;
var a2 = 'hello';
var a3 = null;
}复制代码
如今须要思考的是当fn()的时候,局部变量a1它们都保存在什么地方?算法
函数运行时,会建立一个执行环境,这个执行环境叫作执行上下文(Execution Context)。在执行上下文中,会建立一个叫作变量对象(VO)的东西。基础类型都保存在这里了。bash
变量对象也存在与堆内存中,可是因为变量对象有特殊的功能,因此咱们仍是尽可能将它与堆内存区别看待。函数
引用数据类型(Object)的值是保存在堆内存中的。可是咱们以前也讲过,在javascript中,不容许直接操做堆内存。因此操做对象时,其实是操做对象的引用。所以引用数据类型都是按引用访问的。这里的引用,能够理解为保存在变量对象中的一个地址,该地址与堆内存中的对象相关联。学习
为了更好地理解变量对象与堆内存,下面用一个例子与图解配合讲解。spa
function foo() {
var a1 = 10;
var a2 = 'hello';
var a3 = null;
var b = { m: 20};
var c = [1,2,3];
}复制代码
再来重复一次。函数运行时,会建立一个执行环境,咱们把这个执行环境称为执行上下文。在执行上下文中,会建立一个变量对象(VO)。基本数据类型的值每每都保存在变量对象中。指针
以下图所示,当咱们想要访问堆内存空间中的引用数据类型时,其实是经过引用(地址指针)来访问的。
在前端面试中,咱们经常会遇到这样一个相似的问题。
//demo01.js
var a = 20;
var b = a;
b = 30;
console.log(a); // a ? 这时a的值多少复制代码
//demo02.js
var m = { a:10, b:20};
var n = m;
n.a = 15;
//这时m.a的值是多少?复制代码
当变量对象中的数据发生复制行为时,新的变量会被分配一个新的值。因此基本数据类型只是复制了一个,而引用数据类型了不光是复制了同一个引用地址,而且指向同一个地方。
由于GC的存在,使得咱们在开发时好像并不用那么关心内存的使用问题,内存的分配与回收彻底实现了自动管理(但这并不表明他不会泄漏)。阳波大神说:“了解内存机制有助于本身清晰地认知到本身写的代码在执行过程当中都发生了什么,从而写出更优秀的代码。”
var a = 20;
alert(a + 100);
a = null;复制代码
上面的三条语句,分别对应以下三个过程。
一、分配内存;
二、使用分配到的内存
三、不须要时销毁内存
1与2都好理解。这里主要讲下3.
javascript的垃圾回收主要是依靠"引用"的概念。当一块内存空间中数据可以被访问时,垃圾回收器会认为他是可以“被得到的”。不可以被得到的数据,就会被打上标记,而且被回收内存空间,这种方式叫作标记-清除算法。