var color = "blue";function changeColor() {if (color === "blue") {color = "red";} else {color = "blue";}}changeColor();alert("Color is now " + color);函数changeColor()的作用域链包含两个对象:它自己的变量对象(其中定义着arguments对象)和全局变量的变量对象。可以在函数内部访问变量color,就是因为可以在这个作用域链中找到它。var color = "blue";function changeColor() {var anotherColor = "red";function swapColors() {var tempColor = anotherColor;anotherColor = color;color = tempColor;// 这里可以访问color、anotherColor和tempColor}// 这里可以访问color、anotherColor,不能访问tempColorswapColors();} // 这里只能访问colorchangeColor();以上代码供涉及3个执行环境:全局环境、changeColor()的句柄环境和swapColors()的局部环境。 
其中,内部环境可以通过作用域链访问所有的外部环境,但外部环境不能访问内部环境中的任何变量和函数。环境变量之间的联系是线性的、有次序的。每个变量只能向上级搜索作用域链,以查询变量和函数名,即首先在本作用于中查询变量或函数名,如果没有再向上一级作用域链查询,直到顶级作用域。但是任何环境都不能向下搜索作用域链而进入另一个执行环境。
函数参数也被当作变量来对待,因此其访问规则与执行环境中的其他变量相同。
1.延长作用域链
当执行流进入下列任何一个语句时,作用域链就会得到延长:
• try-catch语句的catch块
• with语句
这两个语句会在作用域的前端添加一个变量对象。
对于with语句来说,会将指定的变量添加到作用域链中。对catch语句来说,会创建一个新的变量对象,其中包含的是被抛出的错误对象的声明。
举个例子:
function buildUrl() {var qs = "?debug=true";with(location) {var url = href + qs;}return url;}with语句接收的是location对象,因此其变量对象中包含了location对象的所用属性和方法,这个变量对象被添加到作用域链的前端。当在with语句中引用变量href时(实际引用的是location.href),可以在当前环境变量中找到。当引用变量qs时,引用的是buildUrl()中定义的那个变量,该变量位于函数环境变量对象中。至于with语句内部,则定义了一个名为url的变量,因而url就成了函数执行环境的一部分,可以作为函数的值被返回。if(true) {var color = "blue";}alert(color);// "blue"在JavaScript中,if/for语句创建的变量声明会将变量添加到当前的执行环境中。例如:for(var i = 0; i < 10; i++) {doSomething(i);}alert(i);// 10垃圾回收function problem() {var objA = new Object();var objB = new Object();objA.someOtherObj = objB;objB.someOtherObj = objA;}上面的例子中,objA和objB通过属性相互引用。函数执行完成后,objA和objB将继续存在,它们的引用计数不会为0。这种情况会导致objA和objB所占的内存无法回收。