使用循环在数组中存储闭包函数

时间:2015-07-23 16:23:40

标签: javascript functional-programming

这是代码:

  

我将功能体存储在" resultArr "的每个元素中。   ,问题是,当我调用存储的函数_class[0]()时,我无法达到i它总是4!

var checkAttendanceFunc = function(nameArr) {
  var resultArr = [];

  for(var i = 0; i < nameArr.length; i++) {
    resultArr.push(function(){console.log('Is', nameArr[i], 'present?', i);});
  }
  return resultArrultArr;
};

var _class = checkAttendanceFunc(["alex", "brownex", "chris", "mack"]);

我认为很明显,如果我调用_class的任何项目,即_class[0](),索引将为4,名称将为&#34; undefined&#34;

所以我怎么解决这个问题,我看到一些ppl使用apply native函数,但我认为只有当我们存储函数名而不是给定函数的主体时它才有效

2 个答案:

答案 0 :(得分:2)

仍然不确定我是否理解此代码的意图,但这是一个可以执行我认为您正在尝试做的事情的工作版本:

var students = ["alex", "brownex", "chris", "mack"];
var _class = students.map(function(name, i) {
    return function() {
        console.log('Is', name, 'present?', i);
    };
});

在行动here中查看。

如果您真的只是在寻找如何使其与for-loop一起使用,您可以随时捕获它:

var checkAttendanceFunc = function(nameArr) {
    var resultArr = [];

    for(var i = 0; i < nameArr.length; i++) {
        resultArr.push((function(idx) {
            return function() {
                console.log('Is', nameArr[idx], 'present?', idx);
            };
        })(i));
    }

    return resultArr;
};

var _class = checkAttendanceFunc(["alex", "brownex", "chris", "mack"]);

同样,您也可以使用.bind()

var checkAttendanceFunc = function(nameArr) {
    var resultArr = [];

    for(var i = 0; i < nameArr.length; i++) {
        resultArr.push((function(idx) {
            console.log('Is', nameArr[idx], 'present?', idx);
        }).bind(null, i));
    }

    return resultArr;
};

var _class = checkAttendanceFunc(["alex", "brownex", "chris", "mack"]);

无论哪种方式,我个人认为.map()解决方案更加优雅和可读。

答案 1 :(得分:2)

在这种情况下,checkAttendanceFunc内的所有闭包都指向inameArr变量的引用

完成循环后,i对于您生成的所有功能的值为4 ,每次通过时,您需要复制i它关闭了。

有几种方法可以实现这一目标:

立即调用该函数

var checkAttendanceFunc = function(nameArr) {
  var resultArr = [];

  for(var i = 0; i < nameArr.length; i++) {
    resultArr.push(function(index){
        return function(){
            console.log('Is', nameArr[index], 'present?', index);
        }
    }(i));
  }
  return resultArr;
};

在这里你通过关闭的论证,你立即调用它。在这种情况下,i正在复制,并且该函数有自己的值index

使用另一个迭代数组的函数

在这种情况下,我使用Array.forEach

var checkAttendanceFunc = function(nameArr) {
  var resultArr = [];

  nameArr.forEach(function (value, index){
     resultArr.push(function() {
        console.log('Is', value, 'present?', index); 
     }); 
  });
  return resultArr;
};

在这种情况下,创建的函数会收到valueindex的副本,这意味着它们始终指向相同的值