JS进阶系列之做用域链

在以前写的进阶系列里面,提到了执行上下文在建立阶段,要建立变量对象肯定做用域链还有肯定this的指向,本次将重点讲解一下做用域链javascript

JavaScript代码的执行过程

在讲解做用域链以前,首先了解一下,JavaScript代码的执行过程,包括两个步骤:java

  • 编译阶段
  • JavaScript引擎执行阶段

image.png

在编译阶段主要作的是,通过编译器的编译,将代码转化为可执行的代码,其中就包括了做用域规则的肯定,而在以前说的执行上下文的建立和执行阶段是发生在JavaScript隐引擎执行阶段,因此做用域链是在执行上下文建立阶段才产生的,这时候,可能你会疑惑,做用域和做用域链有什么区别呢?函数

什么是做用域?

做用域为一套规则,用来管理引擎如何在当前做用域以及嵌套的子做用域中根据标识符查找变量。this

在JavaScript中,主要的做用域有两种:3d

  • 全局做用域
  • 函数做用域

什么是做用域链?

做用域链是由当前执行环境与上层环境的一系列变量对象组成,它保证了当前执行环境对符合访问权限的变量和函数的有序访问。code

而做用域与做用域链的区别主要在于:对象

做用域是一套规则,做用域链是做用域的具体实现。blog

讲理论可能有些空洞,那么我就举个具体的例子来讲明什么是做用域链吧ip

demo01
var a = 20;
function test(){
        var b = a + 20;
        function innerTest(){
             var c = 10;
             return b + c;
       }
       return innerTest();
}
test();

在这个例子中,按照以前讲解的作用域

  • 先建立执行上下文,按照,globalEC—>testEC—>innerTestEC的顺序,压入调用栈中,其中主要讨论innerTest()的做用域链。
  • 按照做用链的定义,能够得出innerTest()执行上下的结构,以下
innerTestEC = {
      VO:{ c:10},
      scopeChain:[VO(innerTest),VO(test),VO(global)],
      this:{...}
}

能够看出,innerTest()的做用域链就是由当前的执行环境与上层的执行环境中的一系列变量对象组成,因此innerTest()就能访问到上层执行上下文中,变量对象中的属性和方法,这就是做用域链。

  • 看一下innerTest()的做用域链图,以下:

image.png

相关文章
相关标签/搜索