|
1 | | -# 执行环境与作用域 |
| 1 | +# 执行环境(上下文)与作用域 |
2 | 2 | 1. **执行环境(`execution context`),简称为环境,别称:执行上下文**; |
3 | 3 |
|
4 | | -2. 执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为; |
| 4 | +2. 执行环境(上下文)定义了变量或函数有权访问的其他数据,还明确了函数调用时 this 的指向,决定了它们各自的行为; |
| 5 | + |
| 6 | +3. 几种情况的执行环境: |
| 7 | + 1. `func()` 直接调用函数:执行环境默认为 windows |
| 8 | + 2. `func.bind(ctx)()` 或 `apply`, `call` 也可直接指定执行环境 |
| 9 | + 3. `obj.method()` 对象调用方法 === 以该对象做为执行环境执行函数 |
5 | 10 |
|
6 | 11 | 3. 变量对象:`JS` **解析器层面概念**,代码层面无法访问,解析器处理数据时后台使用 |
7 | | - >每个**执行环境**都有一个与之关联的**变量对象**,**环境中定义的所有变量和函数都保存在这个对象中**。 |
| 12 | + >每个**执行环境**都有一个与之关联的**变量对象**,**环境中定义的所有临时变量和函数都保存在这个对象中**。 |
8 | 13 |
|
9 | | -4. 执行环境具有分层机制,**全局执行环境** 是最外围的一个执行环境,在 `Web` 浏览器中,全局执行环境是 **`window`** 对象,所有 **全局变量** 和函数都是做为 window 对象的属性和方法创建的; |
| 14 | +4. 执行环境具有分层机制,**全局执行环境** 是最外围的一个执行环境,在 `Web` 浏览器中,全局执行环境是全局对象,所有 **全局变量** 和函数都是做为 window 对象的属性和方法创建的; |
10 | 15 | ```javascript |
11 | 16 | var foo = "bar"; |
12 | 17 | alert(window.foo); // "bar" |
|
16 | 21 | } |
17 | 22 | window.addSum(1, 1); // 2 |
18 | 23 | ``` |
19 | | -5. 每个函数也有自己的**执行环境**,某个执行环境中的 **所有代码执行完毕后**,该环境被 **销毁**,保存在其中的所有变量和函数定义也随之被销毁; |
| 24 | +5. 每个函数也有自己的**执行环境**,某个执行环境中的 **所有代码执行完毕后**,该环境被 **销毁**,~~保存在其中的所有变量和函数定义也随之被销毁~~; |
| 25 | + > 不一定被销毁,需要看是否有闭包的存在,闭包的存在与否决定该执行环境的变量对象是否会被销毁 |
20 | 26 |
|
21 | 27 | 6. 全局环境直到应用程序退出 -- 例如**关闭网页**或**浏览器**时才会被销毁; |
22 | 28 |
|
23 | 29 | 7. **执行流** |
24 | 30 | > `JS` 脚本代码流式执行,当 **执行流进入一个函数**,函数的 **环境就会被推入一个环境栈** -- 由各个层级环境组成的栈,此时 **程序的控制权在该函数手中**;函数执行完后,栈将其环境弹出,把控制权返回给之前的执行环境 |
25 | 31 |
|
26 | | -8. 作用域链:一个函数,活动对象最开始时只包含一个变量,即 `arguments` 对象;作用域链中的下一个 **变量对象** 来自 **包含(外部)环境**,再下一个变量对象则来自下一个包含环境。这样一直延续到全局执行函数。 |
| 32 | +8. 作用域链:一个函数,活动对象最开始时只包含一个变量,即 `arguments` 对象(特殊的一点:全局执行环境不存在此对象);作用域链中的上一个 **变量对象** 是 **包含(外部)环境** 的变量对象,再下一个变量对象则来自下一个包含环境。这样一直延续到全局执行环境。 |
27 | 33 | > 代码在一个执行环境中执行时,会创建变量对象(见 *No.3*)的一个作用域链:**作用域链是针对变量对象来说的** |
28 | 34 | <br> |
29 | 35 | > **作用域链的用途**:保证对 **执行环境有权访问**(前提条件) 的所有变量和函数的**有序访问**(从作用域链下端向上端访问) |
30 | 36 | <br> |
31 | | -> **作用域链的前端**:始终是 当前执行的代码 所在环境的 **变量对象**;如果环境是函数,则将其 **活动对象** (activation object)作为 **变量对象** |
| 37 | +> **作用域链的前端**:始终是当前执行的代码所在环境的 **变量对象**;如果环境是函数,则将其 **活动对象** (activation object)作为 **变量对象** |
32 | 38 | <br> |
33 | | -> **作用域链的最后端**:全局执行环境的变量对象始终是作用域链中的最后一个对象 |
| 39 | +> **作用域链的最后端**:全局执行环境的变量对象(即全局对象)始终是作用域链中的最后一个对象 |
34 | 40 |
|
35 | 41 | 9. 作用域链的一个实例: |
36 | 42 | ```javascript |
|
48 | 54 | swapColors() |
49 | 55 | } |
50 | 56 | ``` |
51 | | - 作用域链图示:矩形表示特定的执行环境 |
| 57 | + 作用域链图示:矩形表示特定的作用域 |
52 | 58 |
|
53 | 59 | ![2016-02-07_152019.jpg-18.4kB][1] |
54 | 60 | 上述代码设计 3 个执行环境:全局环境、`changeColor()` 局部环境、`swapColors()` 局部环境 |
55 | 61 | * 全局环境的变量对象由 **`color` 变量、`changeColors()` 函数** 组成 |
56 | 62 | * `changeColors()` 局部环境的变量对象由 `anotherColor` 变量、`swapColors()` 函数组成 |
57 | 63 | * `swapColors()` 局部环境的变量对象由 `tempColor` 变量单独构成 |
58 | 64 |
|
59 | | -10. **标识符解析** -- 上级回溯机制:沿着作用域链一级一级有序地搜索标识符的过程;从作用域链的前端开始,逐级后溯,直到找到标识符(无法找到标识符,通常会报错); |
| 65 | +10. **标识符解析**(即变量解析) -- 上级回溯机制:沿着作用域链一级一级有序地搜索标识符的过程;从作用域链的前端开始,逐级后溯,直到找到标识符(无法找到标识符,通常会报错); |
60 | 66 |
|
61 | 67 | 11. 函数参数也被当作变量来对待,访问规格与函数执行环境中的其他规则相同。 |
62 | 68 |
|
|
0 commit comments