在以前写的进阶系列里面,提到了
执行上下文
在建立阶段,要建立变量对象
、肯定做用域链
还有肯定this的指向
,本次将重点讲解一下做用域链
。javascript
在讲解做用域链以前,首先了解一下,JavaScript代码的执行过程,包括两个步骤:java
在编译阶段主要作的是,通过编译器的编译,将代码转化为可执行的代码,其中就包括了做用域规则的肯定
,而在以前说的执行上下文的建立和执行阶段是发生在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()
的做用域链图,以下: