前端

JavaScript作用域和预解析

2019-04-30  本文已影响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级作用域, 所以还是一个全局函数
上一篇 下一篇

猜你喜欢

热点阅读