映像-作用域

2018-06-15  本文已影响15人  zhaochengqi

概念赏析:

执行环境(execution context)
有时也可叫做执行上下文,定义了当前环境下可访问的其他数据。执行环境有 全局执行环境函数执行环境(eval执行环境类比函数执行环境)。

变量对象(variable object)
变量对象是与执行上下文对应的概念,上下文中定义的所有成员都保存在这个对象中。
该对象仅供解析器使用,开发者无法访问

活动对象 (activation object)
活动对象是在函数被调用时创建的,最开始时只包含一个变量:arguments 对象。
函数执行环境将其活动对象作为变量对象

环境栈 (context stack)
每个函数都有自己的执行环境。当执行流进入一个函数时,函数的环境就会被压入一个环境栈中。在函数执行之后,栈将其环境弹出(环境被销毁,保存在其中的变量和函数定义也随之销毁;但闭包会改变这一行为),把控制权交还给之前的执行环境。

全局执行环境
在Web浏览器中被认为是window对象(window对象作为变量对象?)。
因此所有全局变量、函数都是作为window对象的属性和方法创建的。全局执行环境是最外围一个执行环境,直到应用关闭才会被销毁

作用域链 (scope chain)
当代码在一个环境中执行时,会创建一个作用域链来指向变量对象,以保证对执行环境有权访问的变量、函数的有序访问。
作用域链的前端始终是当前执行代码所在环境的变量对象,而作用域链中的下一个变量对象来自外部(包含)环境,一直延续到全局执行环境。全局执行环境的 变量对象 始终是作用域链中的最后一个对象

图 1. 作用域

LHS vs RHS
标识符解析是沿着作用域链一级一级地搜索标识符的过程,始终从作用域链的前端开始,逐级向后回溯。查找类型有两种:LHS和RHS。
L 和 R 的含义是 赋值操作的左侧或右侧。


词法作用域

大部分标准语言编译器的第一个工作阶段叫作词法化(也叫单词化)。词法化的过程会对源代码中的字符进行检查,如果是有状态的解析过程,还会赋予单词语义。

作用域共有两种主要的工作模型:

JavaScript 中的作用域就是词法作用域。
简单地说,词法作用域就是定义在词法阶段的作用域。也可以理解为,词法作用域是由你在写代码时将变量和块作用域写在哪里来决定的,因此当词法分析器处理代码时会保持作用域不变(大部分情况下是这样的,eval、with会修改作用域)。

看一下例子:

function foo(){
  console.log(a)
}
function bar(){
  var a = 3;
  foo()
}
var a = 2
bar() // 输出 2
//词法作用域让foo的作用域链前端的下面是全局变量对象。
//如果JS具有动态作用域,那么理论上应该输出3,因为顺着调用栈可以找到bar的作用域。

由此可见,JS作用域链的生成是基于代码中的作用域嵌套,而不是基于栈调用的。

上一篇 下一篇

猜你喜欢

热点阅读