• JavaScript


    参考

    https://www.jianshu.com/p/3b5f0cb59344
    https://jingyan.baidu.com/article/4f34706e18745be386b56d46.html
    https://www.2cto.com/kf/201401/273825.html
    https://www.cnblogs.com/zqzjs/p/5497955.html

    运行机制

    JavaScript代码的执行是由浏览器中的JavaScript解析器来执行的。JavaScript解析器执行JavaScript代码的时候,分为两个过程:预解析过程和代码执行过程。即先解析(例如先进行变量、函数的声明提升),后运行。

    JavaScript 运行分为两个阶段:
    
    - 预解析
      - 全局预解析(所有变量和函数声明都会提前;同名的函数和变量函数的优先级高)
      - 函数内部预解析(所有的变量、函数和形参都会参与预解析)
        - 函数
        - 形参
        - 普通变量
    - 执行
    
    先预解析全局作用域,然后执行全局作用域中的代码,
    
    在执行全局代码的过程中遇到函数调用就会先进行函数预解析,然后再执行函数内代码。
    
    

    1. 预解释/预处理,变量提升(Hoisting)

    预解析过程:

    1. 把变量的声明提升到当前作用域的最前面,只会提升声明,不会提升赋值。
    2. 把声明式函数(JS有赋值式函数/函数表达式var f = function(){},这个不能被提升)的声明提升到当前作用域的最前面,只会提升声明,不会提升调用。
    3. 先提升var,在提升function

    打印2次2。因为foo()提升到当前作用域的顶部。

    function foo() {
        console.log('1');
    };
    
    foo();
    
    function foo() {
        console.log('2');
    };
    
    foo();
    

    JS解释器逐个块(一个<script>就是一个块)解释。先到第一个<script>,f1提升到全局作用域(打印哈哈)。到第二个<script>,最新的function f1的声明提升到全局作用域,当然执行最新的一个声明(打印嘎嘎)。

        <script>
            function f1() {
                console.log("哈哈");
            }
    
            f1();
        </script>
        <script>
            f1();
    
            function f1() {
                console.log("嘎嘎");
            }
        </script>
    
        <script>
            f1();
        </script>
    

    // 1、-----------------------------------
    var num = 10;
    fun();
    function fun() {
      console.log(num);
      var num = 20;
    }
    //2、-----------------------------------
    var a = 18;
    f1();
    function f1() {
      var b = 9;
      console.log(a);
      console.log(b);
      var a = '123';
    }
    // 3、-----------------------------------
    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);
    }
    

    2. 作用域

    在ES5之前JS没有块级作用,有函数作用域。用函数作用域可以避免多个<script>的全局变量污染。先可以认为JS一般没有块级作用域,有函数作用域。
    块级作用域: "{}内部声明的变量只能够在{}内部访问到,在{}外部无法访问到其内部声明的变量"

    3. 作用域链

    当我们在局部作用域中,访问一个变量时,系统首先会在当前作用域中寻找变量var的声明语句,如找到则直接使用。反之,则继续向上一级作用域中寻找var的声明语句,如找到则直接使用,反之,继续向上一级作用域中去寻找…直到全局作用域

    例子,尝试注释掉每个f的num

        <script>
    
    
            var num = 10;
    
            function f1() {
                var num = 20;
    
                function f2() {
                    var num = 30;
    
                    function f3() {
                        var num = 50;
                        console.log(num);
                    }
    
                    f3();
                }
    
                f2();
            }
    
            f1();
        </script>
    


    4. 隐式全局变量

    在function里,用var定义的变量是局部变量;不用var定义的变量为隐式全局变量

            function f1() {
                var a;//局部变量
                a = 9;
                //隐式全局变量
                b = 9;
                c = 9;
                console.log(a);//9
                console.log(b);//9
                console.log(c);//9
            }
    
            f1();
            console.log(c);//  9
            console.log(b);// 9
            console.log(a);//报错
    
  • 相关阅读:
    audio元素
    获取页面中出现次数最多的三个标签以及出现次数
    vue ssr(server side rendering)
    python_2 python的编码声明
    python_1 python的编译过程
    bugs
    isPrototypeOf和 instanceof 的区别
    WebStorm 配置Git
    MongoDB 副本集搭建
    获取结算样式 getComputedStyle-currentStyle
  • 原文地址:https://www.cnblogs.com/allen2333/p/9147447.html
Copyright © 2020-2023  润新知