1、作用域
作用域是一套规则,用来确定在何处以及如何查找标识符。在 JS 中作用域分为全局作用域和函数作用域,另外函数作用域可以互相嵌套。在下面的例子中,存在着全局作用域 fn 作用域和 bar作用域,他们相互嵌套。
<script>
var a = 1;
var b = 2;
function fn(x) {
var a = 10;
function bar(x) {
var a = 100;
b = x + a;
return b;
}
bar(20);
bar(200);
}
fn(0);
</script>
2、作用域链
各个作用域的嵌套关系组成一条作用域链。例子中 bar 函数的作用域链式 bar -> fn -> 全局, fn函数保存在作用域链式 fn -> 全局
作用域链主要是进行标识符(变量和函数)的查询,标识符解析就是沿着作用域链一级一级的搜索标识符的过程,而作用域链就是保证对变量和函数的有序访问。
(1)如果自身作用域中声明该变量,则无需使用作用域链
在上面的例子中,如果要在 bar 函数中查询变量 a ,则直接使用 LHS 查询,赋值为 100 即可。
(2)如果自身作用域中未声明该变量,则需要使用作用域链进行查找
3、自由变量
在当前作用域中存在但未在当前作用域中声明的变量叫自由变量 。如 bar 函数中的变量 b 就是一个自由变量。
注意:在程序中如果存在自由变量,那么一定存在作用域链。
4、执行环境
执行环境( execution context )也叫上下文、执行上下文环境。每个执行环境都有一个与之关联的变量对象(variable object ),环境中定义的所有变量和函数都保存在这个对象中。
JavaScript 代码执行的环境非常重要,而执行环境可以归纳为以下三种:
(1)全局代码( Global Code ) : 代码首次执行时的默认环境
(2)函数代码( Function Code ) : 程序执行到函数体内时
(3)Eval 函数代码( Eval Code ) : 内置 Eval 函数计算的字符串
<script>
var a = 1;
var b = 2;
function fn(x) {
var a = 10;
function bar(x) {
var a = 100;
b = x + a;
return b;
}
bar(20);
bar(200);
}
fn(0);
</script>
以上述代码为例来说明:在 fn 这个函数中保存有 x、a、bar 环境变量,另外还保存了this、arguments 环境变量。
![](https://i-blog.csdnimg.cn/blog_migrate/2232c2794130cd65ec37c731b9476451.png)
5、执行流程
所谓执行流,就是程序执行的顺序。
![](https://i-blog.csdnimg.cn/blog_migrate/43ffb12f20eb62349691163bae69e0a9.png)
它的执行顺序为:
先执行 var a = 1 ,然后再执行 var b = 2 ,接下来执行 fn(0) ,再执行 var a = 10 ,再执行 bar(20),再执行 var a = 100 ,再执行 b = x + a ,再执行 return b ,再执行 bar(200) ,再执行 var a = 100,再执行 b = x + a ,再执行 return b ,最后程序结束。
JavaScript 的运行时流程图如下:
![](https://i-blog.csdnimg.cn/blog_migrate/43ca6c6f7d57b41d3b1d818e81359518.png)
6、执行栈
当打开网页或浏览器时, 宿主环境 会将代码传递给 引擎 去执行,引擎首先会创建一个全局执行环境。全局环境中的代码自上而下有顺序的执行,当遇到一个函数时,函数的环境被创建,函数中
的代码开始执行;而在函数执行之后,控制权又返还给之前的环境。 ES 这种类似于 " 栈 " 的控制
机制,称为 执行栈 。简单的说,执行环境栈就是一个压栈和出栈的过程。
(1) 宿主环境:浏览器或者 Node 环境。
(2)引擎:从头到尾负责整个 JavaScript 代码的编译及执行过程。
(3)栈:一种遵循 " 后进先出 " 原则的有序数据集合,可以简单理解为使用 push() 和 pop() 操作数组。
下面以示例来进行说明:
<script>
console.log(1);
function pFn() {
console.log(2);
(function cFn() {
console.log(3);
}());
console.log(4);
}
pFn();
console.log(5);
// 输出:1 2 3 4 5
</script>
示意图:
![](https://i-blog.csdnimg.cn/blog_migrate/a9e445516336db92e0abf9c2d11de0fa.png)
![](https://i-blog.csdnimg.cn/blog_migrate/b82043af9e80c296ad352adaef710149.png)