码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 【踩坑录】Javascript的预解析


    Javascript的预解析

          • 1.变量提升/变量预解析
          • 2.函数提升/函数预解析
          • 3.踩坑记录
            • 3.1 坑一知识点:let声明的变量无法进行变量提升,因此必须先声明后使用
            • 3.2 坑二知识点:var声明的变量被赋值了函数,但是也是属于变量提升
            • 3.3 坑三:加入作用域链后,变量提升和函数提升综合使用遇到的问题
            • 3.4 坑四:当全局变量和局部变量混入JS预解析当中

    在Javascript当中,存在 预解析 这么一个词儿。解释它之前,这得提及到JS引擎的运行机制:

    JS引擎运行javascript分为2步:
    	1.预解析
    	2.代码的顺序执行
    
    • 1
    • 2
    • 3

    由此可见,预解析是JS引擎的首个步骤。

    预解析:把js里面所有的 var还有function提升到当前作用域的最前面
    
    预解析的组成部分:
    	1.变量预解析(变量提升):把所有涉及var的变量声明提升到当前的作用域最前面,但不提升赋值操作
    	2.函数预解析(函数提升) :把所有的函数声明提升到当前作用域的最前面,但不调用函数
    
    • 1
    • 2
    • 3
    • 4
    • 5

    为了方便理解,下面举一些例子。

    1.变量提升/变量预解析

       // 1)变量提升:将var声明的变量提升到js作用域的最前面,但是不提升变量的赋值
        console.log(name);
        var name = '晓晓';
        
        // 上面的执行顺序:
        // var name; // 变量提升
        // console.log(name); 
        // name = '晓晓';
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    运行结果:
    在这里插入图片描述

    2.函数提升/函数预解析

       // 2) 函数提升 :把所有的函数声明提升到当前作用域的最前面,但不调用函数
       	f1();
        function f1() {
            console.log("What a nice day!");
        }
        
        // 上面的执行顺序:
        // function f1() { // 函数声明
        //     console.log("What a nice day!");
        // }
        // f1(); // 代码的顺序执行
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    运行结果:
    在这里插入图片描述

    3.踩坑记录

    3.1 坑一知识点:let声明的变量无法进行变量提升,因此必须先声明后使用
    // 报错1: name is not defined
     console.log(name);
     name = '元元'; 
     
    // 报错2:Cannot access 'name2' before initialization
     console.log(name2);
     let name2 = '淳淳'; 
    
    // 正确:先声明/初始化,后调用
     let name3 = '元淳';
     console.log(name3);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    3.2 坑二知识点:var声明的变量被赋值了函数,但是也是属于变量提升
    // 报错1: f2 is not a function
     f2();
     var f2 = function() {
         console.log("I'm a music lover.");
     }
    
     // 其执行的步骤
     // var f2;
     // f2();
     // f2 =  function() {
     // console.log("I'm a music lover.");
     // }
     
    // 正确:先声明/初始化,后调用
      var f2 = function() {
            console.log("I'm a music lover.");
      }
      f2();
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    3.3 坑三:加入作用域链后,变量提升和函数提升综合使用遇到的问题
     // 运行结果: undefined
          var num = 10;
          f1();
          function f1() {
              console.log(num);
              var num = 20;
          }
    
          // 原因:由于作用域链的原因,根据就近原则,控制台打印的num是f1()里面的num。
          // 此段代码包含了变量提升和函数提升。关键在于变量提升,导致f1()的该num先被声明,然后再依次执行console语句、num的赋值,因此输出的是undefined
    
          // 解决方法:将num2的初始化语句提前
          // 运行结果:20
          var num2 = 10;
          f2();
          function f2() {
              var num2 = 20;
              console.log(num2);
          }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    3.4 坑四:当全局变量和局部变量混入JS预解析当中
     f3();
     console.log('外部:c = ' +  c);
     console.log('外部:b = ' +  b);
     console.log('外部:a = ' +  a); // 这一步报错,导致下面的'+++'输出无法执行 原因:a不是全局变量
     console.log('+++++++++++++++++++++++++++++++');
     function f3() {
         var a = b = c = 9;  // 这部分属于集体声明,相当于var a = 9;b = 9;c = 9; 由于b和c未被定义,因此b和c被当作全局变量,而a被视为局部变量
         console.log('--------------------------');
         console.log('内部:c = ' +  c);
         console.log('内部:b = ' +  b);
         console.log('内部:a = ' +  a);
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    运行结果:

    在这里插入图片描述

  • 相关阅读:
    解码2022中国网安强星丨从“移动应用”到“万物互联”,梆梆安全做物联网时代的安全“守门人”
    数据结构-顺序表
    想学C语言,跟着一个大佬学,中间一步错,后面就步步错,我该怎么办啊?
    【CKA考试笔记】十四、helm
    OJ平台代码模板自动生成
    9.8 段错误,虚拟内存,内存映射 CSAPP
    基于jsp/ssm的互联网就医系统的设计与实现
    一次IOS通知推送问题排查全过程
    007_补充_ Pytorch 反向传播和Neural ODE的反向传播
    GO sync.Map Store、Delete 、Load 、Range等方法使用举例
  • 原文地址:https://blog.csdn.net/kokunka/article/details/126121488
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号