JavaScript-闭包

在此之前,希望我们已经了解了作用域链的概念。

首先我们来看一个问题:

           function text() {
               var arr=[];
               for (var i=0;i<10;i++) {
                   arr[i]=function () {
                       document.write(i+" ");
                   }
               }
               return arr;
           }
           var a=text();
           for (var i=0;i<a.length;i++) {
               a[i]();
           }

打印什么结果?偷笑

很简单咯,0 1 2   .... 9咯 哈哈

现实是这样的:


我艹,尴尬

为什么会这样了?


我们先来看一个简单的例子:

           function a() {
               function b() {
                   var bbb = 234;
                   document.write(aaa);
               }
               var aaa=123;
               return b;
           }
           var glob=100;
           var demo=a();
           demo();

打印结果是123.

我们从底层来理解一下这个问题。

代码先预编译,一开始遇到了a函数的声明,和glob变量.

到var demo=a()时,执行a函数,此时a函数的作用域链:


这个首先得先明白!然后开始b函数的定义,此时b函数的作用域链将直接用它爸爸(a)的作用域链,那么此时变成:


b函数比较厚脸皮直接就用a的了,注意这里它们指向的都是同一个地方!!!

然后a函数结束了,然后a函数恢复到它定义的时候,然后它的AO就没有了(注意我这里其实用词不准,希望引起注意),其实AO并没有消失,它还在,但是a函数的作用域链已经不”指向“它了。此时变成了这样:


b函数在a函数结束前被丢出来了,被赋给demo了,然后执行demo();生成了自己的作用域链AO,然后b函数根据自己的作用域链来执行代码(找变量aaa) 自己的AO没有,就找a的作用域链,然后找到了,输出123.

我们现在应该明白,销毁什么函数,变量,其实没有销毁,只是没有指向它的地址了,它还在内存中保存着。(题外话:自己的硬盘的,电脑,存储信息的东西不要随便丢掉!"心怀鬼胎"的人可以通过一些手段,完全可以弄出来的。有没有删掉的照片有一天自己又冒出来的经历闭嘴

闭包就是这样形成的,一个函数的内部有另外一个函数,内部函数通过外部函数的return 返回到外部形成了闭包,享受外部函数的资源(作用域链)


一开始的问题:

           function text() {
               var arr=[];
               for (var i=0;i<10;i++) {
                   arr[i]=function () {
                       document.write(i+" ");
                   }
               }
               return arr;
           }
           var a=text();
           for (var i=0;i<a.length;i++) {
               a[i]();
           }

为什么会是10个10了,现在应该明白了,因为10个arr[]函数与一个text变量形成了一个闭包(1对10)

它们公用了一个变量i,而text函数结束时i变量是10。


闭包的解决方案:

我们首先了解立即执行函数点击打开链接

我们就要输出0 1 2 .... 9怎么办

上面输出10个10的原因俩个:

1:形成了1对10的闭包

2:公用了变量i

我们先看一下这段代码:

            function text() {
               var arr=[];
               for (var i=0;i<10;i++) {
                   (function(j) {
                       arr[j]=function (){
                           document.write(j+" ");
                       }
                   }(i))
               }
               return arr;
           }
           var a=text();
           for (var i=0;i<a.length;i++) {
               a[i]();
           }

这段代码就解决了,怎么解决的了?

1:我们生成了10个函数(虽然是立即执行函数,但还是10个)10对10

2:虽然是立即执行函数,但是它的作用域链没有消失咯,被相应的arr保存了,执行的时候就找到j了,而j并不是共享的。

立即执行函数用于解决闭包问题非常方便,基本上就是此方法了。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值