理解执行环境和作用域
执行环境(execution context)是JavaScript的一个重要概念,它定义了变量或函数有权访问的其他数据,决定了它们各自的行为.每个执行环境都有一个与之关联的变量对象,环境中定义的变量和函数都在这个对象里.
执行环境有全局环境和函数执行环境,执行环境中所有代码执行完后则被销毁(包括所有变量和函数).
全局环境
:最外围的执行环境,在web浏览器中指window对象,所有全局变量和函数都是作为window对象的属性和方法创建的.全局执行环境在关闭浏览器等情况时才会被销毁
函数执行环境
:每个函数都有自己的执行环境,当执行流进入一个环境时,函数的环境会被推入环境栈.函数执行完后,栈将函数弹出,将控制权返回之前环境.当代码在函数中运行会创建一个变量对象的一个作用域链(scope chain),作用域链的作用是,保证对执行环境有权访问的所有变量和函数的有序访问.作用域链的前端始终是当前执行环境的变量对象,函数中的对象则是arguments对象.作用域链下一个变量对象是包含环境,一直包裹直到全局环境.
var color = "red";
function change(){
if(color == "red"){
color = "blue"
}else{
color = "red"
}
};
change();
//这个作用域链则包含连个对象,一个全局对象和自己的变量对象,其中包含arguments对象
查询属性会沿着作用域链往上搜索作用域链,这些环境之间是线性有次序的.
执行环境除了上述作用,还有一个重要作用是:垃圾回收
垃圾回收有两种方式:
- 标记清除:这种方法也是JavaScript最常用的方法,当变量进出环境时会被标记,垃圾收集器在运行时会给存储正在内存中的所有变量都加上标记,然后去掉环境中的变量和被环境中变量引用的变量的标记.之后再被加上标记的变量将被视作准备清除的变量,因为已经无法被引用
- 引用计数:这种方法跟踪记录每个指的引用次数,当声明一个变量并将另一个引用类型值赋给该变量,这个引用次数就是1,这个值又被赋值给了一个变量,则次数+1,当包含这个值引用的变量又取得了另一个值,则次数-1,当次数为0则说明没法访问了,这时就会将占用的空间收回.