深入理解JavaScript作用域和作用域链

本文深入解析JavaScript中的作用域概念,包括静态作用域和动态作用域的区别,以及作用域链的工作原理。通过具体代码示例,阐述了函数在执行时如何查找和访问变量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作用域

JavaScript中作用域是指可访问变量的集合(对象、函数也是变量)。
作用域规定了程序在执行时该如何查找变量,也就是确定当前执行代码对变量的访问权限。
作用域分为:词法作用域(静态作用域)、动态作用域。

那么什么是静态作用域,动态作用域呢?

静、动态作用域

JavaScript中采用的是词法作用域(静态作用域)。
静态作用域:函数的作用域在函数定义时就决定了。
动态作用域:函数的作用域在函数调用时才决定。
下面是一个例子能更好区分两者:

 var value = 5;

 function f1(){
     console.log(value);
 }
    
 function f2(){
     var value = 10;
     f1();
 } 
 f2(); //5

可以看到最后的结果输出是:5
分析如下:
假设JavaScript中采用的是静态作用域,函数f1在定义时作用域就已经决定了,即执行函数f1()时,先在函数内部查找是否有变量value,如果没有则在上一层作用域查找,此时全局变量value就是所查找结果,即value=5,输出结果就是:5
假设JavaScript中采用的是动态作用域,函数f1执行的是,先从函数内部查找是否有变量value,如果没有就查找 f2 函数的作用域,发现 f2 函数局部作用域中有value变量,即输出结果应为:10
已经介绍过JavaScript采用的是静态作用域,所以这段代码最后执行的结果是:5

再看下面一个例子:

var name = 'zsl';
function foo(){
    var name = 'zc';
        function bar(){
            return name;
        }
    return bar();
}
console.log(foo()); //zc


var name = 'zsl';
function foo(){
    var name = 'zc';
        function bar(){
            return name;
        }
    return bar;
}
console.log(foo()());//zc

由结果看见上面两个结果都是zc
分析如下:
JavaScript 函数的执行用到了作用域链,这个作用域链是在函数定义的时候创建的。嵌套的函数 bar() 定义在这个作用域链里,其中的变量 name一定是局部变量,不管何时何地执行函数 bar(),这种绑定在执行 bar() 时依然有效。这个例子也更好的解释了JavaScript采用的是静态作用域。

作用域链

当代码在一个环境执行时,会创建变量对象的一个作用域链。
那么什么作用域链呢?
作用域链:我的理解就是当函数执行时会首先在局部作用域中查找相关变量,如果没有则就再去上一层(父级)作用域中查找,然后逐级向上层作用域中查找,直到到达作用域最顶端(全局作用域),这种一层一层的关系,就构成了作用域链。
下面是一个例子:

var name = 'zsl';
var bodys = 'good';

function foo1(){
    var name = 'zc';
    var age = 18;
        function foo2(){
            var lives = 'learning';
                function foo3(){
                    var height = 180;
                        function foo4(){
                            var st = 3;
                            console.log(st);
                            console.log(height);
                            console.log(lives);
                            console.log(age);
                            console.log(name);
                            console.log(bodys);
                        }
                    return foo4();
                }
            return foo3();
        }
    return foo2();
}
foo1();
//3
//180
//learning
//18
//zc
//good

注意:当代码在执行时是沿着作用域链一级一级地查找,查找过程始终是从作用域链的前端开始然后逐级向上查找,直到作用域链最顶端(全局作用域)为止,如果还是找不到相关变量,通常会导致错误发生。
作用域链的前端:始终都是当前执行的代码所在环境的变量对象。
作用域链的作用:是保证对执行环境有权访问的所有变量和函数的有序访问。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值