做用域与做用域链

做用域
  • 在JavaScript中,咱们能够将做用域定义为一套规则,这套规则用来管理引擎如何在当前做用域以及嵌套的子做用域中根据标识符名称进行变量查找。
这里的标识符,指的是变量名或者函数名
  • JavaScript中只有全局做用域与函数做用域(由于eval咱们平时开发中几乎不会用到它,这里不讨论)。
  • 做用域与执行上下文是彻底不一样的两个概念。我知道不少人会混淆他们,可是必定要仔细区分。
JavaScript代码的整个执行过程,分为两个阶段,代码编译阶段与代码执行阶段。编译阶段由编译器完成,将代码翻译成可执行代码,这个阶段做用域规则会肯定。执行阶段由引擎完成,主要任务是执行可执行代码,执行上下文在这个阶段建立。
过程
做用域链
回顾一下上一篇文章咱们分析的执行上下文的生命周期,以下图。

 

咱们知道函数在调用激活时,会开始建立对应的执行上下文,在执行上下文生成的过程当中,变量对象,做用域链,以及this的值会分别被肯定。以前一篇文章咱们详细说明了变量对象,而这里,咱们将详细说明做用域链。
做用域链,是由当前环境与上层环境的一系列变量对象组成,它保证了当前执行环境对符合访问权限的变量和函数的有序访问。
为了帮助你们理解做用域链,我咱们先结合一个例子,以及相应的图示来讲明。
var a = 20;
 
function test() {
var b = a + 10;
 
function innerTest() {
var c = 10;
return b + c;
}
 
return innerTest();
}
 
test();
在上面的例子中,全局,函数test,函数innerTest的执行上下文前后建立。咱们设定他们的变量对象分别为VO(global),VO(test), VO(innerTest)。而innerTest的做用域链,则同时包含了这三个变量对象,因此innerTest的执行上下文可以下表示。
innerTestEC = {
VO: {...}, // 变量对象
scopeChain: [VO(innerTest), VO(test), VO(global)], // 做用域链
}
咱们能够直接用一个数组来表示做用域链,数组的第一项scopeChain[0]为做用域链的最前端,而数组的最后一项,为做用域链的最末端,全部的最末端都为全局变量对象。
不少人会误解为当前做用域与上层做用域为包含关系,但其实并非。以最前端为起点,最末端为终点的单方向通道我认为是更加贴切的形容。如图。
注意,由于变量对象在执行上下文进入执行阶段时,就变成了活动对象,这一点在上一篇文章中已经讲过,所以图中使用了AO来表示。Active Object
是的,做用域链是由一系列变量对象组成,咱们能够在这个单向通道中,查询变量对象中的标识符,这样就能够访问到上一层做用域中的变量了。
 
 
做者:这波能反杀
來源:简书
著做权归做者全部。商业转载请联系做者得到受权,非商业转载请注明出处。
相关文章
相关标签/搜索