理解JS中的执行上下文与作用域

98 阅读2分钟

执行上下文(作用域)

上下文的定义

界定变量或函数在作用域链上的范围,每个变量或者函数都有其属于的上下文

上下文分类

1 执行上下文分为:全局上下文、函数上下文、块级上下文 2 全局上下文是最外层的上下文,在浏览器中全局上下文指window对象 3 所有通过var定义的全局变量和函数都会成为window对象的属性和方法,但是使用let和const的顶级声明不会定义在全局上下文中

如何判断变量或函数的上下文

  1. 声明位置:
  • 全局作用域:在全局作用域中声明的变量或函数属于全局上下文
  • 函数作用域:在函数内部声明的变量或者函数属于函数上下文
  1. 声明方式:
  • 使用var声明的变量和函数最终都会成为window对象的属性和方法,因此其上下文为全局上下文
  • 使用let和const声明的变量和函数作用域范围为块级作用域,块级作用域没有自己的上下文
  1. 对象属性:
  • 当一个对象的方法是一个函数时,该函数被调用时的上下文是该对象

变量对象

每个上下文都有与其关联的变量对象(底层架构访问不到),这个变量对象上集成了该上下文的变量和函数

作用域链

上下文中的代码在执行过程中,会形成一条关于变量对象的线性作用域链

作用域链作用

当访问某一变量或者函数时,会沿着这条作用域链,从内部上下文向外部上下文逐一进行查询。不可逆性,决定了外部上下文都不能到内部上下文中搜索变量或函数。 简而言之,界定变量或函数作用域的范围

作用域链的执行规则

代码执行时标识符的解析是通过沿作用域链逐级搜索标识符名称完成的。搜索过程始终从作用域链最前端开始,逐级往后,直至找到标识符

例证

   var color = 'blue';
   function changeColor(){
       var anotherColor = 'red';
       function swapColors(){
           var tempColor = anotherColor;
           anotherColor = color;
           color = tempColor;
           //color和anotherColor都可以被访问到
       }
       //tempColor在这里无法被访问到
    }
graph TD
window --> changeColor -->swapColor

整段代码总共有window、changeColor()、swapColor()三个上下文,则对应着有三个变量对象形成的作用域链。作用域链的查找方向是从内上下文swapColor()向外进行寻找的,因为不可逆性,所以tempColor变量无法被访问到。