您的位置:首页 > Web前端 > JavaScript

JavaScript初学笔记之<执行环境及作用域>

2015-06-16 21:24 477 查看
执行环境(execution context,也称为作用域)是JavaScript中最为重要的一个概念。执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为。每个执行环境都有一个与之关联的变量对象(这个变量对象存储了环境中定义的所有变量和函数),环境中定义的所有变量和函数都保存这个对象中(我们编写的代码无法访问这个对象,但解析器在处理数据时会在后台使用它)

全局执行环境是最外围的一个执行环境。根据ECMAScript实现所在的宿主环境不同,表示执行环境的对象也不一样。在Web浏览器中,全局执行环被认为是winndow对象,因为所有全局变量和函数都是作为window对象的属性和方法创建的。某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之摧毁。

每个函数都有自己的执行环境(然后会有一个与之关联的变量对象和作用域链,当函数被调用时,会创建一个执行环境及相应的作用域链;在创建函数时,会创建一个预先包含全局变量对象的作用域链,这个作用域链被保存在内部的[[Scope]]属性中,当调用函数时,会为函数创建一个执行环境,然后通过复制函数的[[Scope]]属性中的作用域链构建起执行环境的作用域链。当执行流进入一个函数时,函数的环境就会被推入一个环境栈中(即函数被调用时),而在函数执行完毕后,栈将其环境弹出,把控制权返回给之前的执行环境。ECMAScript程序的执行流正是有这个方便的机制控制着。

当代码在一个环境(具体来说可以说是函数环境,函数也是对象,也就是对象环境)中执行时,会创建变量对象(这个变量对象保存了函数环境中定义的所有变量和函数)的一个作用域链(只要执行,就会存在作用域链)。作用域链的用途是保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的前端,始终都是当前执行的代码所在环境的变量对象。如果这个环境是函数,则将其活动对象作为变量对象。活动对象在最开始时只包含一个变量,即arguments对象。作用域链中的下一个变量对象来自包含环境,而再下一个变量对象则来则下一个包含环境。这样,②一直延续到全局执行环境;全局执行环境的变量对象始终都是作用域链中的最后一个对象。

标识符解析是沿着作用域链一级一级地搜索标识符的过程。③搜索过程始终从作用域链的前端(而前端始终是当前执行代码所在环境的变量对象)开始,然后逐级地向后回溯,直至找到标识符为止。

以上标着①②③的重点记住。

请看下面的示例代码:

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;

//执行环境是swapColors(),在该环境定义的变量是tempColors。然后根据作用域链会有其他属性的访问权限。这里可以访问tempColor(swapColors变量对象中存储的)、anotherColor(swapColors环境的包含环境变量对象所有的)、color(changeColor环境的包含环境变量对象所有的)

}

//当前执行环境是changeColor,在该环境定义的是anotherColor和swapColors函数。这里可以访问anotherColor、color,不能访问tempColor(根据③这个规则可以知道)

swapColors();

}

//当前执行环境是全局环境,在该环境中定义了color属性和changeColor函数,这里只能访问color。这里的this是window

changeColor();

注意点:

1、使用var声明的变量会自动被添加到最接近的环境中。在函数内部,最接近的环境就是函数的局部环境;在with语句中,最接近的环境是函数环境。如果初始化变量时没有使用var声明,该变量会自动被添加到全局环境。

2、if和for语句中的变量声明会将变量添加到当前的执行环境中,因为没有块级作用域。

3、this对象是在运行时基于函数的运行环境(即在那个执行环境中调用的)绑定的;在全局环境中,this等于window,而当函数被作为某个对象的方法调用时,this等于那个对象。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: