javascript-作用域和作用域链

loading 2022年11月22日 55次浏览

1. 作用域

作用域就是变量和函数生效的区域集合,决定了代码区块中变量和其他资源的可见性。

(1) 全局作用域

任何不在函数或是大括号中声明的变量,都在全局作用域下。全局作用域下声明的变量可以在函数任意位置访问。

(2) 函数作用域

也叫做局部作用域,如果一个变量是在函数内部声明的它就在一个函数作用域下面。这些变量只能在函数内部访问,不能在函数以外去访问。

比如全局作用域读不到函数内部作用域中的变量,除非使用闭包

        function myFunction() {
            let inVariable = "函数内部变量";
        }
        myFunction();//要先执行这个函数,否则根本不知道里面是啥
        console.log(inVariable); // Uncaught ReferenceError: inVariable is not defined

(3) 块级作用域
在大括号中使用let或const声明的变量存在于块级作用域中,大括号之外不能访问这些变量。(var定义的是可以访问到的)

        {
            // 块级作用域中的变量
            let greeting = 'Hello World!';
            var lang = 'English';
            console.log(greeting); // Prints 'Hello World!'
        }
        // 变量 'English'
        console.log(lang);
        // 报错:Uncaught ReferenceError: greeting is not defined
        console.log(greeting);

2. 词法作用域

词法作用域,又叫静态作用域。是指变量在创建阶段就确定好了,而非执行阶段确定的。js遵循的就是词法作用域。

3. 作用域链

当在js中使用一个变量时,首先js会尝试在当前作用域下去寻找,如果没找到再到上层作用域中寻找,直到找到变量或到达全局作用域。

如果全局作用域下仍然找不到该变量,它就会在全局范围内隐式声明该变量(非严格模式)或者直接报错。

        const sex = 'female';

        function person(){
            const name = 'yoimiya';

            function student(){
                const age = 21;
                console.log(name); //yoimiya
                console.log(sex); //female
            }
            student();
            console.log(age); // 报错
        }
        person();

student属于最内层作用域,找不到name就从上一层寻找;找不到sex就从上一层再上一层寻找,直到在全局作用域找到。

person()内部输出age时找不到,向上一层也即全局作用域寻找,还是找不到则报错。