JavaScript——关于预解析的那点小事

什么是预解析

JavaScript属于编程语言,JavaScript 代码是由浏览器中的 JavaScript 解析器来执行的。JavaScript 解析器在运行 JavaScript 代码的时候分为两步:预解析和代码执行。

  • 预解析:在当前作用域下, JS 代码执行之前,浏览器会默认把带有 var 和 function 声明的变量在内存中进行提前声明或者定义。
  • 代码执行: 从上到下执行JS语句。
    预解析会把变量和函数的声明在代码执行之前执行完成。

预解析也叫做变量、函数提升。
变量提升(变量预解析): 变量的声明会被提升到当前作用域的最上面,变量的赋值不会提升。
函数提升: 函数的声明会被提升到当前作用域的最上面,但是不会调用函数。

案例1

我们来看下下面这个例子,大家觉得最后的运行结果是什么呢?

<script>
        var num = 1;
        function demo() {
            console.log(num);
            function demoSon() {
                num = 3;
                console.log(num);
            }
            var num = 2
            demoSon();
        }
        demo();
    </script>

运行结果是 underfined
和你预想的是否有差距呢?

我们来分析以下他的执行步骤:

   // 相当于顺序执行了以下操作----------------------------
        // 变量提升
        var num; 
        // 函数提升 , 但不会调用 ,不调用不执行           
        function demo() {   
             // 当前作用域(即函数demo()里面) 变量提升 
            var num;            执行3. 当前作用域内定义一个num
             // 当前作用域(即函数demo()里面)函数提升   不调用不执行        
            function demoSon() { 
                // 未定义直接赋值,此时作用域链指向demo()中的num
                num = 3;
            }
            console.log(num);   执行4、打印num 作用域链指向执行3的num(当前作用域函数demo内)
                                       定义未赋值  所以结果为underfined
            num = 2             执行5.  给函数demo里面的num赋值     打印在前,赋值在后
            demoSon();          执行6. 调用demoSon()后demo中的num 值变为3; 全局变量num不做更改 
        }
        //提升变量但是变量赋值不会提升
        num = 1;                执行1. 给num 赋值为1
        demo();                 执行2. 调用demo( 

案例2

下面是一个经典的面试题

f1();
        console.log(c);
        console.log(b);
        console.log(a);
        function f1() {
            var a = b = c = 9;
            console.log(a);
            console.log(b);
            console.log(c);
        }

执行结果如下:在这里插入图片描述

我们也来分析一下这个案例的执行过程:

        // 相当于顺序执行了以下操作----------------------------
        //函数提升到最前
        function f1() {
            //当前作用域(函数f1内)变量提升到最前
            var a; 
            a = b =c = 9;
            //var a = b = c = 9; 
            等同于var a = 9 ; b = 9 ; c = 9 ; 
            // b 和 c 直接赋值没有var声明   函数中没有声明直接赋值当全局变量看 
            此时 a 在函数中被定义,属于局部变量只能在函数内使用。 b与c为全局变量
            //与集体声明不一样  var a = 9, b = 9 , c = 9;
            console.log(a);           执行2. 打印a   结果为 9
            console.log(b);           执行3. 打印b   结果为 9
            console.log(c);           执行4. 打印c   结果为 9
        }
        f1();                        执行1. 调用f1()

        console.log(c);              执行5. 打印c   结果为 9
        console.log(b);              执行6. 打印b   结果为 9
        console.log(a);              执行7. 打印a   结果报错,全局变量a未被定义

总结

  • 预解析就是执行JavaScript代码前,浏览器会默认把带有 var 和 function 声明的变量在当前作用域下进行提前声明或者定义,提前声明的变量,赋值不会提升,函数不调用不会执行。
  • 变量定义只在当前作用域有效,作用域之外视为未被定义
  • 函数中没有声明直接赋值的变量当全局变量看
  • 作用域、预解析会影响代码的执行结果,需要仔细分析。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值