作用域与作用域链

本文介绍了JavaScript中的作用域概念,包括全局作用域和函数作用域,以及它们之间的嵌套。作用域链用于标识符的查找,确保有序访问。文章还讨论了自由变量、执行环境(全局、函数和Eval代码)以及执行流程。最后,解释了执行栈的工作原理,如何管理函数调用和控制流。
摘要由CSDN通过智能技术生成

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 环境变量。

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>

示意图:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值