白驹过隙,这篇文章距今已有一年以上的历史。技术发展日新月异,文中的观点或代码很可能过时或失效,请自行甄别:)

基本类型和引用类型

  1. JS变量有两种类型:基本类型和引用类型.其中基本类型的值来源于以下5种基本数据类型:Undefined,Null,Boolean,Number,String.引用类型值指的是那些保存在对内存中的对象,对象中保存的实质上只有一个指针,这个指针指向内存中的另一个位置,该位置保存对象.对保存基本类型值的变量我们说他们是按值访问的,因为我们操作的是他们实际保存的值.
  2. 虽然引用类型的值大小不固定但是内存地址的大小固定,因为可以将内存地址保存在栈内存中,查询时先读取出内存地址在找到保存在堆中的值.
  3. 对于引用类型的值我们可以为其添加属性和方法,也可以改变和删除其属性和方法.
  4. 包含引用值类型值的变量其实包含的并不是对象本身,而是一个指向该对象的指针.从一个变量想另一个变量赋值引用类型的值复制的其实是指针,两个变量最终对指向同一个对象.

执行环境的总结

  1. 执行环境有全局执行函数(也叫全局函数)和函数执行环境之分.
  2. 每次进入一个新执行环境都会创建一个用于搜索变量和函数的作用域链.
  3. 函数的局部环境有权访问呢函数作用域中的变量,而且有权访问其父环境和全局环境.
  4. 全局函数只能访问全局环境中定义的变量和函数,而不是直接访问局部环境中的任何数据
  5. 有些语句可以在作用域的前端临时增加一个变量对象,改变量对象会在代码执行后被移除.具体来说,当执行流进入进入一下任意一个语句时,作用域链就会得到加强:try-catach语句,with语句.
  6. JS没有块级作用域链.某个环境为了度取货写入引用一个标识符时,通过搜索来确定该标识符代表什么.搜索顺序为从作用域链的前段开始向上逐级查询给定名字匹配的标识符.如果在局部环境中找到该标识符,搜索过程停止.

JS内存回收机制

分为了标记清除(目前主流)以及引用计数两种方法.在代码中存在循环引用现象时,引用计数算法就会导致问题.如下代码:

var element=document.getElementById('some_element');
var myObject=new Object();
myObject.element=element;
element.someObject=myObject;

这里对象myObject有一个element属性指向了element对象,而对象element中也有一个someObject属性指向myObject对象.因为存在循环引用,这两个的内存永远都不会被回收.

解决办法

解除这两个值的引用,让其值脱离执行环境,让垃圾收集器下次运行时将其回收.上个例子可以这样:

myObject.element=null;
someObject.element=null