欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JavaScript作用域及作用域链

程序员文章站 2024-02-17 16:31:46
...
    只有函数可以制造作用域结构,那么只要是代码,就至少有一个作用域,即全局作用域,
 凡是代码中有函数的,那么这个函数就构成另一个作用域,如果函数中还有函数,
 那么在这个函数中就又可以诞生一个作用域。
 
 将这样的所有的作用域列出来,可以有一个结构:函数内指向函数外的链式结构。就称为作用域链
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    
</body>
<script>
    var a = 3;
    function f1(){
        function f2(){
            function f3(){
                console.log(a);
            }
        }
    }
</script>
</html>

我们看上面的JS代码,函数里面又写了几个函数,然后我们打印一下试试,看结果:
JavaScript作用域及作用域链
这个打印出了是没有的,怎么回事,我们这段代码,说了,函数声明了,是不是得调用了啊,我们调用一下试试,我们看这样函数怎么调用:

<script>
    var a = 3;
    function f1(){
        function f2(){
            function f3(){
                console.log(a);
            }
            f3();
        }
        f2();
    }
    f1();

</script>
</html>

JavaScript作用域及作用域链

看这个调用代码,直接调用 f1(); ,那虽然说调用了,但是 f1 函数里面什么都没有啊,只有 f2 ,只能是在调用 f2 ,那么在看 f2 ,也是什么都没有,只有 f3 ,那就只能在调用 f3 了,f3 里面才有打印,打印的就是我们声明的变量赋值,所以才出现了这样的函数调用。

那么这时就有一个问题了,我这个 a ,既没有在 f3 里面声明,也没有在 f2 里面声明,更没有在 f1 里面声明,就只是在全局作用域中声明了一个变量a,在局部作用域中是没有的

那我们在看:

<script>
    var a = 3;
    function f1(){
    
        function f2(){
        
            function f3(){
                var a = 4;
                console.log(a);
            }
            f3();
        }
        f2();
    }
    f1();

</script>
</html>

我们看这次直接在 f3 里面声明变量,看结果是 4 还是 3 呢:
JavaScript作用域及作用域链

我们在看几个:

下面是在f2,里面声明:

<script>
    var a = 3;
    function f1(){
    
        function f2(){
        	var a = 5;
            function f3(){
                // var a = 4;
                console.log(a);
            }
            f3();
        }
        f2();
    }
    f1();

</script>
</html>

JavaScript作用域及作用域链

再从 f1 里面声明:

<script>
    var a = 3;
    function f1(){
    	var a = 6;
        function f2(){
        	// var a = 5;
            function f3(){
                // var a = 4;
                console.log(a);
            }
            f3();
        }
        f2();
    }
    f1();

</script>
</html>

JavaScript作用域及作用域链
如果我们再把a = 6,注释掉了,在看呢:

<script>
    var a = 3;
    function f1(){
    	// var a = 6;
        function f2(){
        	// var a = 5;
            function f3(){
                // var a = 4;
                console.log(a);
            }
            f3();
        }
        f2();
    }
    f1();

</script>
</html>

其实结果就还是3了,就是我们之前定义的变量3:
JavaScript作用域及作用域链

其实细心的可能就会发现了,这个 a ,是不像下面的箭头一样,从下向上找啊:

JavaScript作用域及作用域链

当函数中使用某个变量时,优先在自己的作用域中查找
如果找不到,就会向上一层作用域查找,如果找不到继续向上一层查找,直到全局作用域
如果还找不到就直接报错
这就是: 作用域链