JavaScript高级程序设计(第3版)学习笔记8 js函数(中)
2024-05-06 14:21:10
供稿:网友
6、执行环境和作用域
(1)执行环境(execution context):所有的JavaScript代码都运行在一个执行环境中,当控制权转移至JavaScript的可执行代码时,就进入了一个执行环境。活动的执行环境从逻辑上形成了一个栈,全局执行环境永远是这个栈的栈底元素,栈顶元素就是当前正在运行的执行环境。每一个函数都有自己的执行环境,当执行流进入一个函数时,会将这个函数的执行环境压入栈顶,函数执行完之后再将这个执行环境弹出,控制权返回给之前的执行环境。
(2)变量对象(variable object):每一个执行环境都有一个与之对应的变量对象,执行环境中定义的所有变量和函数就是保存在这个变量对象中。这个变量对象是后台实现中的一个对象,我们无法在代码中访问,但是这有助于我们理解执行环境和作用域相关概念。
(3)作用域链(scope chain):当代码在一个执行环境中运行时,会创建由变量对象组成的一个作用域链。这个链的前端,就是当前代码所在环境的变量对象,链的最末端,就是全局环境的变量对象。在一个执行环境中解析标识符时,会在当前执行环境相应的变量对象中搜索,找到就返回,没有找到就沿着作用域链一级一级往上搜索直至全局环境的变量对象,如果一直未找到,就抛出引用异常。
(4)活动对象(activation object):如果一个执行环境是函数执行环境,也将变量对象称为活动对象。活动对象在最开始只包含一个变量,即arguments对象(这个对象在全局环境的变量对象中不存在)。
这四个概念虽然有些抽象,但还是比较自然的,可以结合《JavaScript高级程序设计(第3版)》中的一个例子来细细体会一下:
代码如下:
// 进入到全局作用域,创建全局变量对象
var color = "blue";
function changeColor(){
// 进入到changeColor作用域,创建changeColor相应变量对象
var anotherColor = "red";
function swapColors(color1, color2){
// 进入到swapColors作用域,创建swapColors相应变量对象
var tempColor = anotherColor;
anotherColor = color;
color = tempColor;
/*
* swapColors作用域内可以访问的对象有:
* 全局变量对象的color,changeColor
* changeColor函数相应变量对象的anotherColor、swapColors
* swapColors函数相应变量对象的tempColor
*/
}
swapColors('white');
/*
* changeColor作用域内可以访问的对象有:
* 全局变量对象的color,changeColor
* changeColor函数相应变量对象的anotherColor、swapColors
*/
}
changeColor();
/*
* 全局作用域内可以访问的对象有:
* 全局变量对象的color,changeColor
*/
这里的整个过程是:
(1)进入全局环境,创建全局变量对象,将全局环境压入栈顶(这里也是栈底)。根据前面的关于声明提升的结论,这里创建全局变量对象可能的一个过程是,先创建全局变量对象,然后处理函数声明设置属性changeColor为相应函数,再处理变量声明设置属性color为undefined。