目录

1、作用域

2、作用域链

3、自由变量

4、执行环境

5、执行流程

6、执行栈


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 这个函数中保存有 xabar 环境变量,另外还保存了this、arguments 环境变量。

5、执行流程

所谓执行流,就是程序执行的顺序。

它的执行顺序为:
先执行 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 的运行时流程图如下:

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>

示意图:

 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐