• 0143 JavaScript预解析:概念、变量预解析、函数预解析、函数表达式声明函数问题、案例


    4.1 预解析的相关概念

    JavaScript 代码是由浏览器中的 JavaScript 解析器来执行的。
    JavaScript 解析器在运行 JavaScript 代码的时候分为两步:预解析 和 代码执行。
    
    • 预解析:在当前作用域下, JS 代码执行之前,浏览器会默认把带有 var 和 function 声明的变量在内存中进行提前声明或者定义。 【提升到当前作用域的最顶部。】

    • 代码执行: 从上到下执行JS语句。

    • 预解析会把变量和函数的声明在代码执行之前执行完成。声明提前,赋值留在原地。】


    4.2 变量预解析

    预解析也叫做变量、函数提升。
    变量提升(变量预解析): 变量的声明会被提升到当前作用域的最上面,变量的赋值不会提升。
    
    console.log(num);  // 结果是多少?
    var num = 10;      // ?
    
    结果:undefined
    注意:**变量提升只提升声明,不提升赋值**
    

    4.3 函数预解析

    函数提升: 函数的声明会被提升到当前作用域的最上面,但是不会调用函数。
    注意:`函数声明代表函数整体,所以函数提升后,函数名代表整个函数,但是函数并没有被调用!`
    
    fn();
    function fn() {
        console.log('打印');
    }
    
    结果:控制台打印字符串 --- ”打印“ 
    

    4.4 函数表达式声明函数问题

    函数表达式创建函数,会执行变量提升,此时接收函数的变量名无法正确的调用:
    
    fn();
    var  fn = function() {
        console.log('想不到吧');
    }
    
    结果:报错提示 ”fn is not a function"
    
    解释:该段代码执行之前,会做变量声明提升,fn在提升之后的值是undefined;而fn调用是在fn被赋值为函数体之前,此时fn的值是undefined,所以无法正确调用
    
            // 1问  
            console.log(num); // 报错
    
    
            // 2问
            console.log(num); // undefined  坑 1
            var num = 10;
            // 相当于执行了以下代码
            // var num;
            // console.log(num);
            // num = 10;
    
    
            // 3问  
            // fn();
            // 【函数整体提升到了前面】
            function fn() {
                console.log(11);
            }
            fn();
    
    
            // 4问
            fun(); // 报错  坑2 
            var fun = function() {
                    console.log(22);
    
                }
            // 函数表达式 调用必须写在函数表达式的下面
            // 相当于执行了以下代码
            // var fun;
            // fun();
            // fun = function() {
            //         console.log(22);
    
            // }
    
            // 1. 我们js引擎运行js 分为两步:预解析、代码执行
            // (1). 预解析 js引擎会把js 里面所有的 var  还有 function 提升到当前作用域的最前面
            // (2). 代码执行  按照代码书写的顺序从上往下执行
            // 2. 预解析分为 变量预解析(变量提升) 和 函数预解析(函数提升)
            // (1) 变量提升 就是把所有的变量声明提升到当前的作用域最前面  不提升赋值操作
            // (2) 函数提升 就是把所有的函数声明提升到当前作用域的最前面  不调用函数
    

            // 预解析案例
            // 案例1
            var num = 10;
            fun();
    
            function fun() {
                console.log(num); // undefined
                var num = 20;
            }
    
            // 相当于执行了以下操作
            var num;
    
            function fun() {
                var num;
                console.log(num);
                num = 20;
            }
            num = 10;
            fun();
    
    
            // -------------------------
    
    
            // 案例2
            var num = 10;
    
            function fn() {
                console.log(num); // undefined
                var num = 20;
                console.log(num); // 20
            }
            fn();
    
            // 相当于以下代码
            var num;
    
            function fn() {
                var num;
                console.log(num);
                num = 20;
                console.log(num);
            }
            num = 10;
            fn();
    
    
            // -------------------------
    
    
            // 案例3
            var a = 18;
            f1();
    
            function f1() {
                var b = 9;
                console.log(a);  // undefined
                console.log(b);  // 9
                var a = '123';
            }
    
            // 相当于以下代码
            var a;
    
            function f1() {
                var b;
                var a;
                b = 9;
                console.log(a);
                console.log(b);
                a = '123';
            }
            a = 18;
            f1();
    
    
    
            // -------------------------
    
    

    // 案例4
    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() {
    //     var a;
    //     a = b = c = 9;
    //     // 相当于 var a  = 9; b = 9; c = 9; b 和 c 直接赋值 没有var 声明 当 全局变量看
    //     // 【不是相当于 c = 9; b = 9; var a  = 9; 因为这里的优先级一样。】
    //     // 集体声明  var a = 9, b = 9, c = 9;
    //     console.log(a);
    //     console.log(b);
    //     console.log(c);
    // }
    // f1();
    // console.log(c);
    // console.log(b);
    // console.log(a);
    

    // 补充案例
    var a = [a, b] = [1, 2, 3];
    console.log(a); // [1, 2, 3]
    console.log(b); // 2
    
    // 上面的代码相当于,注意顺序
    [a, b] = [1, 2, 3]
    console.log(a, b) // 1  2
    var a = [1, 2, 3]
    console.log(a) // [1, 2, 3]
    console.log(b) // 2
    
    

    // 补充
    var a = {n: 1};
    var b = a;
    // 带成员访问的优先级高一些,相当于a.x = {n: 2};  a = {n: 2}
    a.x = a = {n: 2};
    console.log(a.x);
    console.log(b);
    
  • 相关阅读:
    忽略大小写的RegularExpressionValidator
    Outlook 2010 “加载项执行错误。调用“Microsoft Exchange 加载项”加载项时,在“IDTExtensibility2”接口回调“OnConnection”期间,Outlook 出现故障”问题
    选择排序——算法系列
    代码杂记32
    数据库系统原理
    C#中的委托与事件
    C#多线程
    冒泡排序——算法系列
    快速排序——算法系列
    递归算法——猴子吃桃
  • 原文地址:https://www.cnblogs.com/jianjie/p/12151998.html
Copyright © 2020-2023  润新知