JavaScript入门第十八章(js作用域及变量预解析 )

Posted 海海呐

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript入门第十八章(js作用域及变量预解析 )相关的知识,希望对你有一定的参考价值。

1.js作用域

1.作用域:变量起作用的范围

* 2.js中只有两种:全局作用域  局部作用域
           *   * 全局作用域:变量在任何地方起作用
          * 全局变量:在函数外面声明 
  * 局部作用域:变量只能在函数内部起作用(又叫块级作用域)
              * 局部变量:在函数内部声明
<script>

    //1.全局变量
    let a = 10;
    function fn (  ) {
        console.log ( a );
    }
    fn();
    
    //2.局部变量
    function fn1 (  ) {
        let num = 10;
        console.log ( num );
    }
    fn1();
    console.log ( num );
</script>

2.作用域链

  • 1.作用域链是怎么来的

    • 默认情况下,我们的js代码处于全局作用域,当我们声明一个函数时,此时函数体会开辟一个局部作用域, 如果我们在这个函数体中又声明一个函数,那么又会开辟一个新的局部作用域,以此类推,就会形成一个作用域链

  • 2.变量在作用域链上的访问规则

    • 就近原则:访问变量时,会优先访问的是在自己作用域链上声明的变量,如果自己作用域链上没有声明这个变量,那么就往上一级去找有没有声明这个变量,如果有就访问,如果没有就继续往上找有没有声明,直到找到0级作用域链上,如果有,就访问,如果没有就报错

 代码展示:

       let num = 10; // 0级链   全局作用域链
       // 0级作用域
       function f1 (  ) { // 函数变量f1本身还是处于0级链(变量f1本身处在全局作用域中,是一个全局变量。函数体中才是局部变量,也就是局部作用域链)
   
           let num = 20; // 1级链
           console.log ( num ); // 20
   
           function f2 (  ) { // 1级链
               // 2级链
               console.log ( num ); // 20,当前作用域链未声明,就会找上级作用域链的num变量
               num += 100; // 当前作用域链未找到,会从上级寻找 num = 20 + 100
               console.log ( "二级链" + num ); // 2级链  120
           }
           f2();
           console.log ( "一级链" + num ); // 120   为什么不是20:因为二级链上并没有声明变量,而是直接获取父级变量修改
       };
   
       // 0级作用域
       f1();
       // 0级作用域
       console.log ( "0级链" + num );// 10

3.js预解析

  • 1.为什么要有预解析机制?

    • 通过前面的学习我们知道,js代码是从上往下执行的,这样有什么不好的地方呢?

    • 实际开发中,往往一个文件中js代码会有很多的函数,而如果我们都把函数的声明写在最上面,那么我们的业务逻辑就会在下面,这样的话开发效率不高

      • 函数毕竟只是保存一段代码的,我们希望可以将函数写在页面的下面,而把一些业务逻辑功能写在代码上面,这样的话维护起来更方便

  • 2.什么是预解析机制

    • (1)其实js代码并不是从上往下执行的,这种说法不严谨

    • (2)预解析:JS在执行代码之前,会把变量的声明提前到所在作用域的最顶端

      • a.只是声明提前(相当于提前开辟内存空间),变量的赋值与函数的调用还是在原地

      • b.函数的声明也会提前

  • 3.预解析的意义(好处)

    • 让函数可以在任意地方调用

  console.log ( num ); // undefined
       var num = 10;
       console.log ( num ); // 10
   
       /*
       let num;
       console.log ( num );
       num = 10;
       console.log ( num );
        */
   
       fn();
       function fn () {
           console.log ( num );
           console.log ( "嘿嘿嘿" );
           var num = 10;
           console.log ( num );
   
           /*
           // 函数声明提前
           function fn(){
            var num;
           console.log ( num ); // undefined
           console.log ( "嘿嘿嘿" );
           num = 10;
           console.log ( num ); // 10
           }
   
           // 调用语句在原地不变
           fn()
   
            */
       // }

  上一章:JavaScript入门第十七章(内置对象的API)

  下一章:JavaScript入门第十九章(JS补充知识点)(完结)

以上是关于JavaScript入门第十八章(js作用域及变量预解析 )的主要内容,如果未能解决你的问题,请参考以下文章

Docker入门第八章

JS笔记 入门第二

第一百零六节,JavaScript变量作用域及内存

Spring入门第十八课

python入门第二十八天——文件上传

JavaScript入门第十三章(函数)