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

 

 

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.

所以引出了闭包的概念:

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值