zoukankan      html  css  js  c++  java
  • JavaScript预解析:同名变量和函数、同名函数表达式和同名函数声明

    预解析的含义:在写js代码调用函数的时候,无论你是在调用位置的前面或者后面声明函数,都可以正常调用,

    原因是,JavaScript碰到script标签,会将var变量(注意是var)声明函数声明(注意是声明)提升到当前作用域最前面

    预解析结论变量的提升,指的是声明的提升,赋值(初始化)并不会提升

    看一些例子:

    例1:

    //例1
    console.log(num);  
    var num = 2;
    
    //上述代码:解析过程
    var num;            //第一步:预解析       
    //执行过程
    console.log(num);   //第二步:打印结果-->undefined
    num = 2;            //第三步:赋值

    说明:变量声明提升,赋值不提升

    例2:

    //例2:
    var num = 2;
    var num;
    console.log(num);
    
    //上述代码:解析过程
    var num;    //第一步:预解析
    var num;    //第二步:预解析
    num = 2;    //第三步:赋值
    console.log(num);   //第四步:打印结果-->2

    结果不是undefined?因为var 变量是会提升的,提前预解析了,然后又赋值了,所以结果为2。

    扩展-1:

    //扩展-1
    function f() {}
    var f;
    console.log(f);  
    
    //上述代码:解析过程
    function f() {} //第一步:预解析整个函数
    var f;          //第二步:预解析
    console.log(f); //第三步:打印结果-->function f() {}

    按理说,这里应该是undefined,结果不是

    原因:预解析时,当变量和函数同名时,优先留下函数的值(不管谁前或后,函数优先级更高)

    扩展-2:

    //扩展-2
    function f() {
        console.log(num); // undefined
    }
    var num;

    这里函数里面能访问到num,证明变量的声明会在函数声明之前

    这个问题是个人的理解,有疑问的读者也可以去查些资料。 

    例3:

    //例3
    var f = function() {
        console.log(1)
     }
     function f() {
       console.log(2)
     }
     f();  
    
    //上述代码:解析过程
    var f;                          //第一步:预解析
    function f() { console.log(2)}  //第二步:预解析--f整个函数
    f = function() { console.log(1)}//第三步:f赋值整个函数
    f();                            //第四步:执行函数f-->输出1

    例4

    //例4
    f();  
    var f = function() {
      console.log(1)
    }
    function f() {
      console.log(2)
    }
    f(); 
    
    //上述代码:解析过程
    var f;                          //第一步:预解析
    function f() { console.log(2)}  //第二步:预解析--f整个函数
    f();                            //第三步:执行f函数-->输出2
    f = function() { console.log(1)}//第四步:f赋值整个函数
    f();                            //第五步:执行f函数-->输出1

    这个例子和前一个只是函数调用位置发生了改变,结果也变了

    例5:

    //例5
    f(); 
    var f = function(){
        console.log('k')
    }
    
    //上述代码:解析过程
    var f;                              //第一步:预解析
    f();                                //第二步:执行f函数,报错
    f = function(){ console.log('k')}   //第三步:f赋值整个函数

    原因:调用一个未赋值的函数,当然会报错,

    注意:这个例子,将函数表达式换成函数声明就不会报错了,

              因为函数声明会提升,这也是我们常用函数声明的一个原因,可以在任何位置调用。

    例6:

    //例6
    var num = 2;
    function f() {
      num = 1;
      console.log(num)  
      return
      var num = 3;
    }
    f();
    console.log(num); 
    
    //上述代码:解析过程
    var num;                //第一步:预解析
    function f() {          //第二步:预解析--f整个函数
        //解析过程
        var num;            //此处提升的变量是return后面的
        num = 1;            //num赋值
        console.log(num)    //执行时,会输出1 
        return              //后面的代码不会执行
        num = 3; 
    }
    num = 2;                //第三步:num赋值
    f();                    //第四步:执行f函数-->输出1
    console.log(num);       //第五步:输出结果-->2

    说明:return后面的语句虽然不会执行,但是变量还是会提升,所以f函数执行时,会输出1

    例7:

    //例7
    console.log(num);  //报错
    num = 2;

      只有var会提升,隐式全局变量并不会提升,所以结果和例1不同,并不是undefined

    本文引自:https://blog.csdn.net/m0_37897013/article/details/81701016

    其它可借鉴的资料:https://www.jb51.net/article/90113.htm

  • 相关阅读:
    MyBatis初学者配置
    hibernate错题解析
    Hibernate二级缓存配置
    Open Session In View
    Hibernate延迟加载Lazy
    ThreadLocal
    HQL基础查询语句
    Hibernate中saveOrUpdate()和merge()的区别
    springmvc的类型转换
    springmvc的初始化参数绑定
  • 原文地址:https://www.cnblogs.com/ggll611928/p/13156966.html
Copyright © 2011-2022 走看看