首页 > js闭包问题?

js闭包问题?

初学闭包,有下面的疑惑,希望得到高人的指点
第一种形式:

var result = new Array();
    function createFunctions(){         
         for(var i=0;i<10;i++){
             result[i] = function(){             
                 return i;
             };
         }
         return result;
     }
      createFunctions();
     for(var i=0;i<result.length;i++){
          alert(result[i]());
     }//结果每个都是10.

改进后:

var result = new Array();

function createFunctions(){         
     for(var i=0;i<10;i++){
         result[i] = function(){             
             return i;
         }();
     }
     return result;
 }
  createFunctions();
 for(var i=0;i<result.length;i++){
      alert(result[i]);
 }    

//结果是0-9

     那我的问题就是这个算是用闭包解决的吗?内部函数可以访问外部的变量。

再一次修改为:

var result = new Array();
    function createFunction(){         
         for(var i=0;i<10;i++){
             result[i] = function(num){
                 return function(){
                     return num;
                 };
             }(i);
         }
         return result;
         
     }
     createFunction();
     for(var i=0;i<result.length;i++){
          alert(result[i]());
     }
这个是书的用闭包解决最初的问题,我想第二个可以实现,为什么要这么复杂的写法呢?是不我理解的闭包还是有问题,还不知道闭包要是用在哪?    

     

你的方法是把值直接输出。看似效果一致,其实并不是闭包。闭包是从外部访问局部变量,得到的值是通过内部return出来的函数去通过作用域访问到想要的局部变量,书上的那个方法是访问每一次循环的i变量,所以有十个外层函数定义的不一样的i,被return 的十个函数从外部访问,所以需要用result[i]()调用函数获取,而不是固定下来的值。


  1. JS中变量只有函数作用域

  2. JS中变量为词法作用域,也就是变量在声明的时候就确定其作用域

  3. 闭包其实是扩展了函数的作用域链,函数可以使用在其外层函数中声明的变量

你的2中写法实现的目的不同,导致实现的方式的差异
第1中方式:result中保存的是一个结果
第2中方式 result中保存的是一个函数对象,其具有再次执行的能力
看你想要的结果是什么,就用什么样的实现~~~

var result = new Array();
function createFunction(){         
     for(var i=0;i<10;i++){
         result[i] = function(num){
             return function(plus){
                 return num+plus;
             };
         }(i);
     }
     return result;
     
 }
 createFunction();
 for(var i=0;i<result.length;i++){
      console.log(result[i](i));
 }

首先解释一下第一段函数为什么都输出十,因为这段代码运行中会形成闭包

result[i] = function(){             
                 return i;

用到了它的父函数所定义的变量(也就是for中声明的),在这个函数没有结束之前变量并不会被销毁,会得到保留,所以说i的值一直被保留直到完全运行完,所以十个值全都是十。
第二段函数个人认为是解决了闭包的问题,利用了自执行,没次返回后函数会自动立即执行,故可以把i的值实时的送出去。
本人水平有待提高,说的不是很清楚,希望可以对你有用


在回答你这个问题前,说一说闭包。
是之前我给我们公司培训前端知识的时候整理的一些内容,选取其中的部分:

有人说,函数就是“闭包”;
也有人说,闭包是函数的“堆栈”;
还有人说,闭包是一种特殊的对象;

我说,闭包-定义了一个作用域。

(function(){
    //
})();//我不知道这是不是闭包,我当做是

function  fun(){
    //
};//这是函数,其实不是闭包

闭包-知乎说法

闭包-闭包是指在javascript中,内部函数总是可以访问其所在外部函数中声明的参数和变量,即使在其外部函数被返回(寿终正寝)了之后。

我又换一种说法-一个函数将其内部变量(属性、方法)返回,使得可以外部访问,就是构成了闭包。

闭包是魔鬼

刚刚看到的“寿终正寝”之后,依然可以访问,糟糕,内存泄露的问题来了。

很多人把问题归结于闭包,其实是不对的,很大程度上跟自己写的代码有关(网上有相关资料)

闭包是天使

闭包不是魔鬼,其实是长着魔鬼脸的天使

闭包是一些函数型编程语言的特性

闭包允许财产私有化(下面会说私有属性/方法)

闭包对于模块化有大恩大德

其实,你两种方式是差不多的。一种是通过直接访问外部变量(第一种),还有一种是通过参数形式(第二种)。从访问外部变量的角度看,第二种其实没有形成闭包。如果从作用域的角度看,第二种属于闭包。

其实,这些概念性的东西,不要纠结太多,主要是你要有自己的理解。

虽然形式都看似差不多,甚至如你认为的那样,第一种更简洁,孰优孰劣(不仅仅要从书写代码的层面上考虑,上面也提到了一个内存泄露的东西),你可以去多看下,多了解下。

这里,我推荐第二种方式。

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