一文读懂作用域&作用域链

85 阅读3分钟

JavaScript中的作用域是指代码中变量和函数可被访问的范围。在JavaScript中,作用域是静态的,也就是说,在编写代码时,作用域的范围已经确定了。JavaScript中有两种类型的作用域:全局作用域和局部作用域。

全局作用域

全局作用域是整个JavaScript程序的作用域。全局变量和函数可以在程序的任何地方被访问。当在程序中创建一个变量或函数时,如果它没有被创建在任何一个函数内部,那么它就会被分配到全局作用域中。

例如:

var x = 5; 
function foo() { 
    console.log(x); // 输出 5 
}
foo();

在上面的代码中,变量x被分配到了全局作用域中,并且可以在函数foo()中被访问到。

如果在函数内部使用var声明一个变量,那么这个变量就被限定在了函数内部的作用域范围内。

例如:

function foo() { 
    var x = 5;
    console.log(x); // 输出 5 
}
foo();
console.log(x); // 报错,x未定义

在上面的代码中,变量x只能在函数foo()内被访问到,无法在函数外部被访问到。

局部作用域

局部作用域是函数内部的作用域。在函数内部声明的变量和函数只能在函数内部被访问。

例如:

function foo() {
    var x = 5;
    function bar() {
        var y = 10;
        console.log(x, y); // 输出 5 10
    } bar(); 
    console.log(x, y); // 报错,y未定义 
}
foo();

在上面的代码中,变量y只能在函数bar()内被访问到,无法在函数外部或者函数foo()内被访问到。

作用域链

当在一个函数内部引用一个变量或者函数时,JavaScript引擎会先在这个函数内部查找该变量或函数,如果没有找到,就会向上一级作用域中查找,直到到达全局作用域为止。这种查找变量或函数的过程被称为作用域链。

例如:

var x = 10;
function foo() {
    var y = 5;
    function bar() {
        console.log(x, y); // 输出 10 5
    }
    bar(); 
}
foo();

在上面的代码中,函数bar()内部引用了变量xy,由于变量y并没有被定义在bar()内部,JavaScript引擎就会往上一级作用域foo()中查找,直到找到变量y为止。

作用域的注意事项

  • 变量的赋值操作不会影响作用域的范围。例如,在函数内部给一个全局变量赋值,不会影响全局作用域以外的代码中该变量的值。

  • 如果一个变量既出现在全局作用域中,又出现在函数的作用域中,那么函数内部的变量会覆盖全局变量。

  • 在JavaScript中没有块级作用域。例如,在if语句或者for循环中定义的变量,仍然可以在该块后面的代码中被访问到。

总结

作用域是程序中限定变量和函数可访问范围的一种机制。在JavaScript中有两种类型的作用域:全局作用域和局部作用域。JavaScript引擎查找变量和函数时,会沿着作用域链向上查找,直到查找到为止。在JavaScript中没有块级作用域,变量的赋值操作不会影响作用域的范围。