JavaScript学习笔记——变量,作用域和内存管理
JavaScript学习笔记——Javascript基本语法
本文是对《Professional:JavaScript for Web Developers》第四章:Variables,Scope, and Memory所做的笔记
----------------------------------------------------------------------------------
JavaScript中,变量分为两个类型,分别是Primitive类型和Reference类型。
其中,primitive类型主要是五种类型的原子数据:undefined,null, boolean, number, string。这些都是可以直接操纵的实际数据,复制,赋值以及作为参数传递给函数,都是用其固有的数据。
而reference类型是对Object类型的引用;在赋值的时候,指向的仅仅是该Object的指针;复制也是复制其指针;传递给函数的时候,也是传递指针。
可以用valueof()方法来判断到底是何种类型,如果是除了null之外primitive类型,会返回具体类型;如果是Object或者是null,返回Object类型。
用instanceof可以判断该引用是否是某个Object的引用。如alert(person instanceof Object)则会返回true。
关于作用域Scope
有全局变量:所有window对象都是全局变量,全局变量只有在窗口(浏览器)关闭时候才会销毁。
局部变量和全局变量的定义是放在Scope chain中的,scope chain决定寻找变量时候的次序(provide ordered access to all variables and funcitons that an excution context has access to)。scope chain中,全局变量放在最后,每次查找都是先找本地变量;这也解释了本地变量会覆盖全局变量的值;这么做是为了性能的考虑,查找本地变量的开销比较小。
对于for(var i=0 ; i < 10 ; i++){
doSomething();
}
这样的语句,比较特别,alert(i);的结果会是10。这个对在if语句中定义的也是这样。函数的在函数外就变量就失效。
var定义的相当于局部变量(the most immediate content),对于函数就是函数内的范围。
不用var定义的是全局变量,不推荐使用。
垃圾回收机制(Garbage Collection)
垃圾是自动回收的,原则是哪个部分不用就回收哪个部分的。垃圾回收机制一直在运行,它运行在特定的内存区域中。
垃圾回收有两种策略(由浏览器决定):
1.mark-and-sweep策略:
当前所有浏览器都是用这种策略。其思路是给每个变量都做编号,然后标记所有在context中使用的变量或者引用在context中对象(context可以理解为正在执行的上下文)。在垃圾回收机制触发后,将没有标记的变量或者对象移除内存。
2.refence counting策略:
为每个变量设置引用初值0,每次赋值或者引用都+1,覆盖(overwrite)则-1。如果是0则消除。这个只在网景早期的浏览器中使用。弃用的原因是因为会导致循环引用(cirular reference)。在IE8(包括)之前的版本,BOM和DOM也是用该策略垃圾回收的,在IE9中改进了:IE9将BOM和DOM封装为JavaScript的Object。
性能:在IE7之前,当变量数量超过256或者常量个数(包括栈、数组个数)大小超过4096,或者string超过64k中的一个条件之后,便会触发垃圾回收机制,这导致性能很差;之后版本使用动态阀值策略,当达到临界值的15%,则将阀值加倍,达到85%时候,将阀值减半(进入垃圾回收处理)。
内存策略:由于浏览器分配的内存远小于系统分配的内存,因此采用Optimize的内存策略,即仅保持在必要数据在内存。不用的时候将变量dereference,这个之后在out context发生。