31.JavaScript-函数中变量作用域

作用域

1. 在JavaScript中{}外面的作用域,我们称之为全局作用域
2. 在JavaScript中函数后面{}的作用域,我们称之为"局部作用域
3. 在ES6中只要{}没有和函数结合在一起,我们就称之为"块级作用域

4. 块级作用域和局部作用域区别
4.1在块级作用域中通过var定义的变量是全局变量
4.2在局部作用域中通过var定义的变量是局部变量
5. 无论是在块级作用域还是在局部作用域中,省略变量前面的let或者var就会变成一个全局变量,但是在企业开发中,我们及其不推荐省略var或者let去定义变量


作用域链

JavaScript代码中至少有一个作用域, 即全局作用域。凡是代码中有函数,那么这个函数就构成另一个作用域。如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域。将这样的所有的作用域列出来,可以形成的结构就称之为作用域链。

var num = 123; // 0级作用域链
function test() { // 0级作用域链
    var num = 666; // 1级作用域链
    console.log(num);

    function demo() { // 2级作用域链
        var num = 777;
        console.log(num);
    }

    demo();
}

test();
console.log(num);

预解析

JavaScript代码的执行是由浏览器中的JavaScript解析器来执行的。
JavaScript解析器执行JavaScript代码的时候,分为两个过程:预解析过程、代码执行过程
预解析过程:
把变量的声明提升到当前作用域的最前面,只会提升声明,不会提升赋值。
把函数的声明提升到当前作用域的最前面,只会提升声明,不会提升调用。
先提升var,在提升function。

var num = 123;
fun();
function fun() {
    console.log(num);
    var num = 666;
}
/*
var num;
function fun() {
    var num;
    console.log(num);
    num = 666;
}
num = 123;
fun();
*/
var a = 666;
test();

function test() {
    var b = 777;
    console.log(a);
    console.log(b);
    console.log(c);
    var a = 666;
    let c = 888;  //let不会参加预解析


}

/*
var a;
function test() {
    var b;
    var a;
    b = 777;
    console.log(a); // undefined
    console.log(b); // 777
    console.log(c); // 报错
    a = 888;
    let c = 888;
}
a = 666;
test();
*/

你可能感兴趣的:(31.JavaScript-函数中变量作用域)