一执行环境
执行环境 (也叫做执行上下文, Execution Context) 是 Javascript 中最为重要的一个概念执行环境定义了变量或函数有权访问其他数据, 决定了它们各自的行为每个执行环境都有一个与之关联的变量对象, 执行环境中定义的所有变量和函数都保存在这个对象中虽然我们编写的代码无法访问这个对象, 但解析器在处理时会在后台使用它
全局执行环境是最外围的一个执行环境根据 ECMAScript 实现所在的宿主环境不同, 表示执行环境的对象也不一样在 web 浏览器中, 全局执行环境被认为是 window 对象, 因此所有全局对象和函数都是作为 window 对象的属性和方法创建的某个执行环境中的所有代码执行完毕后, 该环境被销毁, 保存在其中的所有变量和函数随之销毁(全局执行环境直到应用程序退出例如关闭网页或浏览器时才被销毁)
每个函数都有自己的执行环境当执行流进入一个函数时, 函数的环境就会被推入到一个环境栈 (也叫做函数调用栈) 中, 同样遵循先进后出后进先出的存取方式而在函数执行之后, 栈将起环境弹出, 把控制权返回给之前的执行环境 ECMAScript 程序中的执行流正是由这个方便的机制控制着
- var color = blue;
- function changeColor() {
- var anotherColor = red;
- function swapColors() {
- var tempColor = anotherColor;
- anotherColor = color;
- color = tempColor;
- }
- swapColors();
- }
- changeColor();
以上代码共涉及三个执行环境: 全局环境 changeColor 的局部环境 swapColors 的局部环境
我们很容易知道:
第一步, 首先是全局环境入栈
全局环境入栈之后, 执行流将其中的可执行代码开始执行, 直到遇到了 changeColor() , 这一句激活函数 changeColor 创建它自己的执行环境, 因此第二步就是执行流将 changeColor 的执行环境入栈
changeColor 的执行环境入栈之后, 执行流开始执行其中的可执行代码, 遇到 swapColors()之后又激活了一个执行环境因此第三步是执行流将 swapColors 的执行环境入栈
在 swapColors 的可执行代码中, 再没有遇到其他能生成执行环境的情况, 因此这段代码顺利执行完毕, swapColors 的执行环境中弹出
swapColors 的执行环境弹出之后, 继续执行 changeColor 的可执行代码, 也没有再遇到其他执行环境, 顺利执行完毕之后弹出这样, ECStack 中就只剩下全局环境了
全局环境在浏览器窗口关闭后出栈
ps: 这个所谓的执行流其实就是指的线程
二作用域链
当代码在执行环境中执行时, 会创建变量对象的一个作用域链作用域链的用途是保证对执行环境有权访问的所有变量和函数的有序访问作用域链的前端, 始终都是当前执行的代码所在环境的变量对象如果当前执行环境是函数, 则将其活动对象作为变量对象活动对象在最开始的时候只包含一个变量, 即 arguments 对象 (这个对象在全局环境中是不存在的) 作用域链中的下一个变量对象来自包含 (外部) 环境, 而再下一个变量对象则来自下一个包含环境这样, 一直延续到全局执行环境; 全局执行环境的变量对象始终都是作用域链中的最后一个对象
ps:this 对象是在运行时基于函数的执行环境绑定的也就是说在执行环境中一旦使用 this, 那么就会给这个 this 指向一个明确的对象
在上述代码中我们可以描述成以下:
标识符解析是沿着作用链一级一级地搜索标识符的过程搜索过程始终从作用域链的前端开始, 然后组件向后回溯, 直到找到标识符为止(如果找不到标识符, 通常会导致错误发生)
在上图中内部环境可以通过作用域链访问所有的外部环境, 但外部环境不能访问内部环境中的任何变量和函数, 这些环境之间的联系是线性有次序的
来源: http://www.bubuko.com/infodetail-2515465.html