JS作用域、作用域链、闭包

本文深入探讨JavaScript中的作用域、作用域链及其在函数执行中的角色,通过实例讲解闭包的形成与应用,揭示变量查找机制及函数执行上下文。

 

 

JS作用域、作用域链

运行期上下文:当函数执行时,会创建一个称为执行期上下文的内部对象。一个执行期上下文定义了一个函数待执行时的环境,函数每次执行时对应的函数上下文都是独一无二的,所以多次调用一个函数会调至创建多个执行上下文,当函数执行完毕时,它所产生的执行上下文被销毁。

查找变量:在那个函数中查找变量就从这个函数的作用域链的顶端一次向下查找。

作用域:

[[scope]]:每个JavaScript 函数都是一个对象,对象中有些属性我们可以访问,有些不可以访问,这些属性仅供js引擎存取,[[scope]]

就是其中一个。

[[scope]]指的是我们所说的作用域,其中存储了运行期上下文的集合。

作用域链:

[[scope]] 中所存储的执行时期上下文对象的集合,这个集合呈链式链接,我们把这种链式链接叫做作用域链。

function a(){
    function b() {
        var b =234;
    }
    var a  =123;
    b();
}
var global =100;
a();

当a在定义时,它就有自己的属性和方法,那么它就具有a.name同理它也有a.scope:

此时a 中有个作用域链:

 

作用域链中存储执行上下文集合,但是此时没有达到集合的程度,此时作用域链中只一个值,即 第0位,此时第0位又指向Global Object 即GO

即当a 函数刚刚被定义的时候 a的scope中就存有东西了,存的就是只有一位的GO,此时GO中有this.window.document.a 函数和golb变量

然后函数a 开始执行那么势必会产生一个AO ,那么这个AO会存放在哪里,此时AO会放到作用域链的顶端。所以如图

由于AO放到了作用域的顶端所以 AO 在第0位GO在第一位

所以如果此时你要在a 函数中访问某个变量是,系统它在a的scope中找而且是从顶端依次向下找 

然后紧接着由于a函数的执行,产生了b函数的定义,所以它也有自己的scope,它的环境是a 给的,

所以当b被创建时,发生如下过程:

 但是此时它是定义并没有执行,所以此时的作用域链没有任何改变

当b 在执行时生成了自己的AO如下图:

它自己同样会生成作用域因为是它本身生成的,那么此时它会放到作用域链的顶端,所以0位置的是本身,1的位置是a,2的位置是GO,所以如果要在b中访问变量是自顶向下的。

如果此时b 被执行完了则断开自己的AO 那么此时a也就被执行完了,则a也断开自己的AO等待下一次被执行,重新生成AO。

例子一

function a(){
    function b() {
        function c() {
        }
        c();
    }
    b();
}
 a();

作用域如下所示:

a defined a.[[scope]] --> 0:GO

a doing   a.[[scope]] --> 0:aAO
                      --> 1:GO

b defined b.[[scope]] --> 0:aAO
                      --> 1:GO

b doing   b.[[scope]] --> 0:bAO
                      --> 1:aAO
                      --> 2:GO

c defined c.[[scope]] --> 0:bAO
                      --> 1:aAO
                      --> 2:GO

c defined c.[[scope]] --> 0:cAO
                      --> 1:aAO
                      --> 2:aAO
                      --> 3:GO
function a() {
    function b() {
        var bbb = 234;
        console.log(aaa);
    }
    var aaa  = 123;
    return b;
}
var glob = 100;
var demo  = a();
demo();

 

 当a执行完也就是 执行return b 之后,应该将其执行上下文销毁如图:

 则图中的红色线被销毁,由于此时a 被销毁了 那么a中的b也应该被销毁了,但是此时b 被返回出来了,所以b 依然存在所以b此时的执行期上下文如图

所以demo()的执行结果为 123。 

例二

function a() {
    var num  = 100;
    function b() {
         num ++;
        console.log(num);
    }
     return b;
}
 var demo  = a();
demo();
demo();

结果:

101

102

a 产生了执行上下文,b在a的基础上定义的所以b能够拿到a 的执行期上下文,所以b定义状态拿的是a 的ao,所以第一次执行demo()的时候,b 找到a 中的num 对其进行加1,然后当再次执行demo()时,由于a已经断开了自己的作用域链,而b 的作用域链没有变,所以当再次执行demo()时,此时num 值还是在b 的ao 中的num ,因为之前的num 是 101 所以此时的num 为102.

所以引出了闭包的概念:

当内部函数被保存到外部时,将会生成闭包 。

【从高压输电线的架空地线中汲取电能】一个25千瓦受控电源从735千伏线路的架空地线中汲取电能的SimPowerSystems模型(Simulink仿真实现)内容概要:本文介绍了一个基于SimPowerSystems的Simulink仿真模型,用于模拟从735千伏高压输电线的架空地线中汲取25千瓦电能的受控电源系统。该模型聚焦于高压输电线路中架空地线的能量回收技术,通过仿真手段实现对电能采集过程的建模与控制策略验证,体现了电力系统中新型能源获取方式的技术可行性与工程应用潜力。文中还提及该资源属于一系列电力系统仿真研究的一部分,涵盖微电网、储能优化、碳流追踪、鲁棒调度等多个前沿方向,配套提供Matlab/Simulink代码及网盘资料链接,便于科研人员复现与拓展研究。; 适合人群:具备电力系统基础知识、熟悉Matlab/Simulink仿真环境,从事电力工程、能源回收或智能电网相关研究的科研人员及研究生;有一定编程与建模仿真经验的高年级本科生或工程技术人员。; 使用场景及目标:①研究高压输电线路中架空地线的能量回收机制与建模方法;②掌握基于Simulink的电力系统仿真技术,特别是受控电源与电网交互的动态特性分析;③为开展能源 harvesting、分布式供能、电力电子变换器控制等相关课题提供参考模型与技术支撑; 阅读建议:建议结合提供的仿真模型文件进行实操演练,重点理解系统结构设计、参数设置与控制逻辑实现;同时可延伸学习文档中提到的其他电力系统优化与仿真案例,以拓宽研究视野和技术积累。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值