当前位置 主页 > 服务器问题 > win服务器问题汇总 >

    深入理解JavaScript高级之词法作用域和作用域链

    栏目:win服务器问题汇总 时间:2019-11-16 16:07

    主要内容:
    1、分析JavaScript的词法作用域的含义

    2、解析变量的作用域链

    3、变量名提升时什么

    最近在传智播客讲解JavaScript的课程,有不少朋友觉得JavaScript是如此的简单,但是又如此的不知如何使用,因此我准备了一些内容给大家分享一下.
    这个系列主要讲解JavaScript的高级部分的内容,包括作用域链、闭包、函数调用模式、原型以及面向对象的一些东西. 在这里不包含JavaScript的基本语法,如果需要了解基础的同学可以到http://net.itcast.cn里面去下载免费的视频进行学习. 好了,废话不多说,直接进入我们的正题.

    一、关于块级作用域
    说到JavaScript的变量作用域,与咱们平时使用的类C语言不同.
    例如C#中下面代码:

    复制代码 代码如下:
    static void Main(string[] args)
    {
     if(true)
     {
      int num = 10;
     }
     System.Console.WriteLine(num);
    }

    这段代码如果进行编译,是无法通过的,因为"当前上下文中不存在名称num". 因为这里
    变量的作用域是由花括号限定的,称为块级作用域.

    在块级作用域下,所有的变量都在定义的花括号内,从定义开始到花括号结束这个
    范围内可以使用. 出了这个范围就无法访问. 也就是说代码
    复制代码 代码如下:
    if(true)
    {
     int num = 10;
     System.Console.WriteLine(num);
    }

    这里可以访问,因为变量的定义与使用在同一个花括号内.

    但是在JavaScript中就不一样,JavaScript中没有块级作用域的概念.

    二、JavaScript中的作用域
    在JavaScript中,下面代码:

    复制代码 代码如下:
    if(true) {
     var num = 10;
    }
    alert(num);

    运行的结果是弹窗10. 那么在JavaScript中变量的作用范围是怎么限定的呢?

    2.1 函数限定变量作用域
    在JavaScript中,只有函数可以限定一个变量的作用范围. 什么意思呢?
    就是说,在JavaScript中,在函数里面定义的变量,可以在函数里面被访问,但是在函数外
    无法访问. 看如下代码:

    复制代码 代码如下:
    var func = function() {
     var num = 10;
    };
    try {
     alert(num);
    } catch ( e ) {
     alert( e );
    }

    这段代码运行时,会抛出一个异常,变量num没有定义. 也就是说,定义在函数中的变量无法
    在函数外使用,当然在函数内可以随意的使用, 即使在赋值之前. 看下面代码:
    复制代码 代码如下:
    var func = function() {
     alert(num);
     var num = 10;
     alert(num);
    };
    try {
     func();
    } catch ( e ) {
     alert( e );
    }

    这段代码运行后,不会抛出错误,弹窗两次,分别是 undefined 和 10(至于为什么,下文解释).

    从这里可以看得出,变量只有在函数中可以被访问. 同理在该函数中的函数也可以访问.


    2.2 子域访问父域
    前面说了,函数可以限定变量的作用域,那么在函数中的函数就成为该作用域的子域. 在子域
    中的代码可以访问到父域中的变量. 看下面代码:

    复制代码 代码如下:
    var func = function() {
     var num = 10;
     var sub_func = function() {
      alert(num);
     };
     sub_func();
    };
    func();

    这段代码执行得到的结果就是 10. 可以看到上文所说的变量访问情况. 但是在子域中访问父域的