#执行环境
执行环境(execution context)是JavaScript中非常重要的一个概念。每个执行环境对应着一个变量对象(variable object),环境中的变量和函数都保存在这个对象中。提到变量与函数,就要意识到这是在环境中的变量与函数。环境决定了变量与函数的行为。

每个函数在被调用时都会创建自己的执行环境。维护一个环境栈。当进入函数体时,将函数创建的执行环境压入栈中;函数执行完毕时,栈将其环境弹出。

那全局变量呢?当然是属于最外围的执行环境了。在Web浏览器中,这个执行环境就对应着window对象。所有全局变量和函数都是作为window对象的属性和方法创建的。当网页关闭时,就尘归尘土归土啦,环境连同其中的变量与函数一同被销毁。

#作用域
代码在执行环境中执行时,由内而外的变量对象就构成了一个作用域链(scope chain)。作用域的开始,是代码所在环境的变量对象;作用域的结束,是全局执行环境的变量对象。

如果执行环境是函数,那么活动对象(activation object)就是变量对象。活动对象在最开始时只包含一个变量,即arguments对象。这个对象是类数组对象。

#作用域链的延长
作用域链的最后一个对象始终是全局执行环境的变量对象。延长指的是在作用域链的前端增加一个变量对象,代码执行后就会被移除。具体而言也就是以下两种情况:

  • try-catch语句的catch块
  • with语句

#块级作用域的困惑
先看一段代码:

1
2
3
4
if (true) {
var color = "blue";
}
alert(color); //"blue"

JavaScript长得和C很像。但是其它类C的语言里,由花括号封闭的代码块都有自己的作用域,因而支持根据条件来定义变量。JavaScript并不支持这点。所以上面这段代码曾经困惑过我。不过了解深入一点之后也就廓然了。