js 作用域与预分析

112 阅读3分钟

1.js 作用域

  1. 分为全局作用域 局部作用域
  2. 全局作用域:整个script 标签 或者js文件为全局作用域
  3. 局部作用域 被函数包裹 只在函数声明赋值 等 为 局部作用域
  4. js是单线程语言,一旦出错,下面的代码不再执行!!!
  5. js是没有块级作用域的
 <script>
        // 分为全局作用域 局部作用域
        // 全局作用域:整个script 标签 或者js文件为全局作用域
        //局部作用域 被函数包裹 只在函数声明赋值 等 为 局部作用域
        var a = 1;// 全局 作用域
        function fn(){
            var num = 10;//局部作用域
        }
        console.log (a);//1 
        console.log(num);//报错
    </script>

2.js是没有块级作用域的

    <script>
        // js是没用块级作用域的
        // 案例 
        if(true){
            var num = 10;
        }

        console.log(num);// 10; 结果为10 证明var num 不仅仅在if中起作用
        还在script 中起作用 及 js没有块级作用域
        
    </script>

js 3.作用域链

  1. 内部函数查找外部函数的变量,采用的是链式查找的方式
  2. 链式查找遵循的基本原则是,向上查找,就近原则
<script>
        //作用域链
        // 内部函数查找外部函数的变量,采用的是链式查找的方式
        // 链式查找遵循的基本原则是,向上查找,就近原则
        // 案例1.
        var num = 10;
        function fn(){
            var num = 30;
            fun()
           function fun(){
                console.log(num);//30 
            /*
            此案例的操作步骤为
            1.现在 fun()内查找 是否有num 无-->2.在fn()中查找 有 num=30 及输出 num=30;停止查找
            */
            }
        }
        fn();
    </script>

4.预解析

js 执行代码时 分为两个步骤 1.预解析 2. 执行代码

  1. 预解析 js引擎会把js内的 var(变量) 和 function(函数)提到作用域的最前面
  2. 函数的提升 function demo() {}(把demo函数提升到前面) var demo = function() {}(只会把demo提升到前面)
  3. 代码执行 从上到下顺序执行
  4. 变量提升是提升到当前的作用域的最前面!!
  5. 如果函数中没有使用var定义变量,外部也没有这个变量,则这个变量为全局变量
<script>
        // 案例1 此案例主要研究 把 var 提到当前作用域的最前面
        console.log(num);//undefined
        var num = 10;
        //案例一 系统实际上是这样执行的
        var num ;//将变量 提升到 最前面
        console.log(num);
        num = 10;


        // 案例2 此案例 主要研究 把 var 提到当前函数的作用域的最前面
        var num = 10;
        function fn(){
            console.log(num);//undefined 
            var num = 30;
            console.log(num);//30
        }
        fn();
         // 案例2 系统实际上是这样执行的
         // 预编译
         var num = 10;
         function fn (){
             var num ;
             console.log(num);
             num = 30;
             console.log(num);
         }
         fn();


        // 案例3 此案例 主要研究 把 函数提到当前的作用域的最前面
         var num = 10;
         fn();
        function fn(){
            console.log(num);//undefined 
            var num = 30;
            console.log(num);//30
        }
        
         //案例3 系统实际上是这样执行的
         //预编译
         var num = 10;
         function fn (){//函数放在 前面
             var num ;
             console.log(num);
             num = 30;
             console.log(num);
         }
         fn();
        f1()
        console.log(a) // js是单线程语言,一旦出错,下面的代码不再执行!!!
        console.log(b)
        console.log(c)
        function f1() {
            var a = b = c =9;
            // 相当于 c = 9; b = c; var a = b
            console.log(a)
            console.log(b)
            console.log(c)
        }

        // 着重强调,如果函数中没有使用var定义变量,外部也没有这个变量,则这个变量为全局变量
    </script>

特别注意

  1. js是单线程语言,一旦出错,下面的代码不再执行!!!
  2. 如果函数中没有使用var定义变量,外部也没有这个变量,则这个变量为全局变量
  3. 变量提升是提升到当前的作用域的最前面!!!
  4. var a=b=c=9为 c=9; b=c var a=b;