美文网首页前端
JavaScript作用域和预解析

JavaScript作用域和预解析

作者: 无尾树袋熊 | 来源:发表于2019-04-30 22:38 被阅读0次

    作用域

    1. JavaScript中也有作用域的概念
    2. 相同作用域内不能有同名的变量和函数, 不同作用域内可以有同名的变量和函数
    3. 如果不同的作用域中出现了相同名称的变量, 那么访问时采用就近原则
        var num = 123;
        function say() {
            var num = 666;
            console.log(num); //666
        }
        say();
    

    作用域链

    1. 默认情况下全局作用域,我们称之为0级作用域

    定义一个函数就会再开启一个作用域,如果该函数是在全局作用域中定义的, 那么我们称之为1级作用域.如果该函数是在其他函数中定义的,那么所在函数+1级作用域

    1. 作用域链的作用

    在使用变量或者函数的时候,会在当前作用域链中查找, 如果找不到, 就会去上一级的作用域链中查找

    1. 在JS中,函数可以嵌套定义
        var num = 666;
        function say() {
            var num = 123;
            var test = function () {
                var num = 777;
                console.log(num); //777
            };
            console.log(num); //666
            test();
        }
    
        console.log(num); //123
        say();
    

    全局变量

    1. 默认情况下在函数中定义的变量都是局部变量
    2. 在函数中定义变量时,没有书写var关键字,那么这个局部变量就会变为全局变量(==企业开发中不能写==)
        function say() {
            num = 666;
            console.log(num);
        }
        say(); //666
        console.log(num); //666
    

    预解析

    1. js是解释性的语言,不需要编译, 边执行边解析
    2. 预解析在JS代码执行前
    3. (预解析)将变量和函数的声明提升到当前作用域的最前面
    console.log(num);//undefined
    var num = 123;
    //1.var num;
    //2.console.log(num);
    //3.num = 123;
    
    say();//hello
    function say() {
        console.log("hello");
    }
    //1. function say() {console.log("hello");}
    //2. say();
    
    1. 预解析练习1:
    var num = 123;
    fun();
    function fun() {
        console.log(num);//undefined
        var num = 666;
    }
    
    1. 预解析练习2
        var a = 666;
        test();
        function test() {
            var b = 777;
            console.log(a); //undefined
            console.log(b); //777
            var a = 888;
        }
    
    1. 预解析练习3

    变量和函数同名时,函数的优先级最高

        console.log(num);//ƒ num() {console.log("hello world");}
        function num() {
            console.log("hello world");
        }
        var num = 666;
        console.log(num); //666
    
    1. 企业开发中:变量名与函数名不能一样,否则会出现混乱问题
    2. 规则:

    如果在同名的变量和函数声明之前访问这个名称, 拿到的是函数

    如果在同名的变量和函数声明之后访问这个名称, 拿到的是变量

        // var num = 123;
        // function num() {
        //     console.log("hello");
        // }
        // console.log(num); //123
    
        console.log(num);//ƒ num() {console.log("hello");}
        var num = 123;
        function num() {
            console.log("hello");
        }
    

    不同方式定义函数的区别

    1. 在高级别的浏览器中,预解析不会提升{}中的函数
    2. 在低级别的浏览器中,预解析会提升{}中的函数
        if (true){
            function test() {
                alert("hello");
            }
        }else {
            var test = function () {
                alert("world");
            }
        }
        test();
        
        //前面我们说过默认都是0级作用域, 也就是全局作用域
        //只有定义了函数才会开启一个新的作用域
        //所以test函数虽然定义在了if的{}中, 但是并没有定义在其它函数中
        //所以test函数还是属于0级作用域, 所以还是一个全局函数
    

    相关文章

      网友评论

        本文标题:JavaScript作用域和预解析

        本文链接:https://www.haomeiwen.com/subject/xdbbnqtx.html