执行环境和作用域

《JavaScript高级程序设计》读书笔记

执行环境是js中最为重要的一个概念。
执行环境定义了变量或函数有权访问的其它数据,决定了它们各自的行为。
每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。

每个函数都有自己的执行环境。当执行流进入一个函数时,函数的环境会被推入到一个环境栈中。而在函数执行之后,栈将其环境弹出,把控制权返还给之前的执行环境。

当代码在一个环境中执行时,会创建变量对象的一个作用域链。它可以保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的前端,始终都是当前执行的代码所在环境的变量对象。如果这个环境是函数,则将其活动对象作为变量对象。作用域链的下一个变量对象来自外部环境,而再下一个变量对象则来自下一个外部环境。这样,一直延续到全局执行环境。

标识符解析是沿着作用域链一级一级地搜索标识符的过程。搜索过程始终从作用域链的前端开始,然后逐级地向后回溯。直到找到为止。

上面的文字真的是很学术化,还是来看一段代码吧:

let color = 'blue';

function changeColor() {
    if (color === 'blue') {
        color = 'red';
    } else {
        color = 'blue'
    }
}

changeColor();

上面的代码定义了一个函数changeColor(),这个函数的作用域链包含两个对象:它自己的变量对象和全局的变量对象。可以在函数内部访问变量color,就是因为在这个作用域链中可以找到它。
在局部作用域中定义的变量可以在局部环境中和全局变量互换使用,例如:

let color = 'blue';

function changeColor() {
    let anotherColor = 'red';

    function swapColor() {
        let tempColor = anotherColor;
        anotherColor = color;
        color = tempColor;

        // 这里可以访问到color/anotherColor/temColor
    }

    // 这里可以访问到anotherColor/color,但是无法访问tempColor
    swapColor();
}
// 这里只能访问到color
changeColor();

内部环境可以通过作用域链访问所有的外部环境。但外部环境不能内部环境中的任何变量和函数。
每个环境都可以向上搜索作用域链,查询变量和函数名;但任何环境都不能通过向下搜索作用域链而进入另一个执行环境。


完。

你可能感兴趣的:(执行环境和作用域)