Skip to content

执行上下文与作用域

执行上下文

四种执行上下文,每个上下文都有一个关联的变量对象,定义了所有这个上下文的变量和函数

  1. 全局上下文。即 window 对象
  2. 函数上下文。每一次函数的调用都会生成一个新的上下文
  3. eval上下文。少用且不建议使用

上下文会在执行时,压入上下文栈中,执行完后再弹出栈,这就是为何能随着作用域链找变量。

在弹出栈后,上下文会被销毁(全局上下文在应用程序退出前才会被销毁)。并把执行权推给下一个上下文。

作用域

三种作用域

  1. 全局作用域,非严格模式下,不加 var 声明一个变量,会被放入全局作用域中
  2. 函数作用域,函数内部声明的变量、参数、argument都会被放入其中
  3. 块级作用域,由最近的一对包含花括号 {} 界定,但只能用来限制 letconst 声明的变量

上下文在调用时,会创建变量对象的一个作用域链,如果是函数上下文还会在最初定义一个变量:argument。

正在执行的上下文的变量对象始终位于作用域链的最前端,如果要搜索标识符,则从当前作用域链开始寻找,逐级往后,直到找到为止,若没找到,则报错。

js
var color = 'blue'

function changeColor() {
    let anotherColor = 'red'
    
    function swapColor() {
        let tempColor = anotherColor
        anotherColor = color
        color = tempColor
    }
    swapColor()
}

changeColor()

作用域链增强

导致作用域链前端临时添加一个上下文,这个上下文在代码执行后会删除

  1. try / catch 语句的 catch 块,会创建一个新的变量,对象包含要抛出的错误对象的声明
  2. with 语句,向作用域链前端添加指定的对象