首页 > 在书中看见的JS例子,有点不太明白

在书中看见的JS例子,有点不太明白

讲的是闭包的问题 函数的执行环境我明白,闭包感觉有点相似于java中的内部类(不知有错没),书上举了一个下面的例子

function createFunctions(){ var result =new Array(); for(var i=0;i<10;i++){ result[i]=function(){ return i; }; } return result; }
书上说函数会返回一个函数数组 但是每个函数都是返回的10,并非自己的索引。这里不太明白...书上把代码改成了

function createFunctions(){ var result =new Array(); for(var i=0;i<10;i++){ result[i]=function(num){ return function(){ return num; }; }(i); } return result; }

说这样就能返回索引了... 头晕了(~@.@~)


这确实是讲闭包的一个典型的例子。

闭包不是JS所特有的,很多语言都有。维基百科上对闭包的定义是“闭包是引用了自由变量的函数”。首先闭包是一个函数,另外一个条件是它引用了自由变量(可以理解为该函数自身以外的变量)。

就你这个问题来说,第一个示例代码中返回的一组函数中却是有对变量i的引用,但是引用的是同一个值i,而随着循环结束,i的值最终变成了10,所以你会输出一堆10

而第二个示例代码中,你返回的函数中有一个变量num,而它是一个自由变量,因为它是其外部函数的一个变量,而不是自身定义的。你实际上返回的是一个闭包。每一次循环都会返回一个新的闭包,所以对于每一个i值都对应有一个闭包。所以你最终可以输出对应的i值。

由于在其他面向对象的语言中很少接触到闭包这个概念,所以刚接触闭包的时候可能会觉得有些难以理解,这很正常,多看些资料,时间长了也就慢慢了解了。

另外,闭包和Java中的内部类是有些许相似,但是闭包比前者更加灵活。

参考连接:


闭包又见闭包...LZ你运行一下第一个createFunctions(),看看你得到结果是什么?

[function () { return i }, function () { return i }, function () { return i }, function () { return i }....]

而不是你想象中的

[function () { return 0},function () { return 1 }, function () { return 2 }, function () { return 3}, ....]

醒醒!这是result[i]带给你的错觉!
这就是闭包,匿名函数function() {return i}; 仅仅代表返回i,那i是多少哪?
当匿名函数执行的时候,从作用域链中寻找,匿名函数的寻i历险记如下:
嗯,我自己的作用域里没定义i,接着往上走,诶!老爹createFunctions的作用域里定义了i,它的值又是多少?这个for循环(十年前就执行完了)里说了i10
好,返回10。函数运行结束。

现在说说第二个createFunctions。首先

=function(num){
  return function(){
    return num;
  };
}(i);

这玩意叫立即执行函数表达式,字面意思,运行到这它立刻就执行了!
i=0时,它立刻就return了一个

function(){
  return num;
};

同第一个分析的一样,我们看看这个num是多少
自己作用域里没num,往上走,诶!老爹(同样没名字)的作用域里有num,作为形参被赋值了0,找到了!
跟祖父createFunctionsi现在是多少有关系吗?毫无关联!


闭包问题还真是常见呢,大概讲下原因吧,题主用到的第二个例子中,我们通过闭包机制将 i 赋值给了 num,继而将值保存在了内存中,因此会依次输出我们想要的结果。
详细机制请题主可参考:

  • 《细说 Javascript 函数篇(三) : 闭包和引用》
  • 《Javascript - 深入闭包机制》

你这什么书这个恶心啊,循环给数组一个函数,还不去执行,里面的i当然带不进去了,不用return那么多函数,只需要让result[i] 等于后面函数自执行不就行了吗?

function createFunctions(){
        var result =new Array();
        for(var i=0;i<10;i++){
            result[i]=(function(){
                return i;
            })();
        }
        return result;
    }

楼主你试试这是不是你想要的东西。

js里任何一个函数都是闭包,别把这个问题想复杂了

这么看来你这本书上代码想实现的结果更简单,是这个:

function createFunctions(){
        var result =new Array();
        for(var i=0;i<10;i++){
            result[i] = i
        }
        return result;
    }

这作者简直没事找事


闭包的值是取的时候的值。你外层函数返回时,里边那些函数没有执行,根本没有访问 i。等你调用它时,它们去访问 i,它们看到,哦,i 等于 10。

【热门文章】
【热门文章】