内存空间的理解
一、三种数据结构:
堆(heap):树状结构。类似书架,可以无序,只要知道书的名字就可取出;好比键值对形式存储
栈(stack):先进后出,后进先出; 类似羽毛球盒子,先放去的在最底下,最后才用到。
队列(queue):先进先出;类似排队买东西,排在前面的先买先出去;
二、变量对象与基础数据类型
JavaScript的执行上下文生成之后,会创建一个叫做变量对象的特殊对象,JavaScript的基础数据类型往往都会保存在变量对象中。
JavaScript的基础数据类型:undefined、Null、Boolean、Number、String、Object。
其中前5种都是直接操作保存在变量中的实际的值。而Object类型(包括Array、function)则是保存在变量对象的一个地址中,该地址与堆内存的实际值相关联。
举例说明:
var a=12; //number类型
var b= "hello"; //string
var c=[1,2,3]; //Array
var d={m:20,n:30} //Object
这样会带来哪些影响呢?
/*
当我们要访问堆内存中的引用数据类型时,
实际上我们首先是从变量对象中获取了该对象的地址引用(或者地址指针),
然后再从堆内存中取得我们需要的数据。
*/
var aa=20;
var bb=aa;
bb=33;
console.log(aa); //20
console.log(bb); //33
/*在变量对象中的数据发生复制行为时,系统会自动为新的变量分配一个新值。
* var bb=aa 执行之后,aa与bb虽然值都为20,但是他们其实已经是相互独立互不影响的值了。
* 所以修改bb的值后,aa的值不会发生变化。
*/
var m={b:10,c:20}
var n=m;
n.b=15;
console.log("n.b为"+n.b); //结果为15;
console.log("m.b为"+m.b); //结果为15;
/* 我们通过var n=m执行复制引用类型的操作。引用类型的复制同样也会为新的变量自动分配
* 一个新的值保存在变量对象中,但不同的是,这个新的值,仅仅只是引用类型的一个地址指针。
* 当地址指针相同时,尽管他们相互独立,但在变量对象中访问到的具体对象其实是同一个。
* 所以改变n时,m也会发生相应的变化。
*/
//解决方法:不引用,新建对象
var cc=new Object();
cc.b=m.b;
cc.b=11;
console.log("cc.b为"+cc.b); // 11
console.log("m.b为"+m.b); // 10
三、内存空间的管理
优化性能的重要方式
JavaScript具有自动垃圾收集*,内存的分配与回收都完全实现了自动管理。
机制原理:找到那些不在继续使用的值,然后释放其占用的空间。每隔一段时间就会执行一次释放操作。
JavaScript的内存周期:
1、分配内存(声明变量)
2、使用内存进行读写操作(定义变量、算法操作)
3、不需要时将其释放、归还 (设为null)
举例:
var a; //分配内存空间
a = 2; //使用内存; 给分配的存储空间赋初值
alert(a+33); //使用内存
a = null; //使用完毕,释放内存
在JavaScript中,最常用的是通过标记清除的算法来找到哪些对象是不再继续使用的,因此 a=null 只是做了一个释放引用的操作,让a原本对应的值失去引用,脱离执行环境,这个值会在下一次垃圾收集器执行操作时被找到并释放。
在局部作用域中,当函数执行完毕,局部变量也就没有存在的必要了,因此垃圾收集器很容易做出判断并回收,但是全局变量什么时候需要自动释放内存空间则很难判断,因此尽量避免使用全局变量。
参照博客:https://yangbo5207.github.io/wutongluo/ji-chu-jin-jie-xi-lie/yi-3001-nei-cun-kong-jian-xiang-jie.html