简体   繁体   English

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

[英]Storing closure functions within array using loop

This is the code : 这是代码:

i'm storing the function body inside each element of " resultArr " , the problem is when i call the stored function _class[0]() i can't reach the exact i it's always 4 ! 我存储函数体“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"]);

i think it's obvious if i call any item of _class ie _class[0]() the index will be 4 and the name will be "undefined" 我认为很明显,如果我调用_class的任何项,即_class[0]() ,索引将为4,名称将为“ undefined”

So how wan i solve this problem, i saw some ppl use the apply native function, but i think it works only if we store the function name not the body of a given function 因此,我如何解决此问题,我看到一些ppl使用了apply native函数,但是我认为只有在我们存储函数名而不是给定函数的主体的情况下,它才起作用

Still not sure I understand the intent of this code, but here's a working version that does what I think you're trying to do: 仍然不确定我是否理解此代码的意图,但是以下是一个有效的版本, 可以满足您的要求:

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

See it in action here . 看到它在这里行动。


If you're really just looking for how to make it work with a for-loop , you could always capture it like this: 如果您真的只是在寻找如何使其与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"]);

Similarly, you can also use .bind() : 同样,您也可以使用.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"]);

Either way, I personally find the .map() solution much more elegant and readable. 无论哪种方式,我个人都认为.map()解决方案更加优雅和可读。

In this case, all the closures inside checkAttendanceFunc point to a reference of the i and nameArr variable. 在这种情况下, checkAttendanceFunc内部的所有闭包checkAttendanceFunc指向inameArr变量的引用

When the loop is done, i 's value is 4 for all the functions you generated , what you need is copying i each time you pass it to a closure. 循环完成后, 对于您生成的所有函数i的值为4 每次将其传递给闭包时,您需要复制i

There are several ways for you to achieve this: 有几种方法可以实现此目的:

Immediately call the function 立即调用函数

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;
};

Here you're passing an argument fo the closure and you call it immediately. 在这里,您为闭包传递了一个参数,然后立即调用它。 In this case, i is getting copied and the function has its own value named index . 在这种情况下, i将被复制,并且该函数具有其自己的名为index的值。

Use another function that iterates on the array 使用另一个在数组上迭代的函数

In this case I'm using Array.forEach 在这种情况下,我正在使用Array.forEach

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

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

In this case the functions created recieve a copy of value and index , which means they will always point to the same values . 在这种情况下,创建的函数将获得valueindex的副本,这意味着它们将始终指向相同的值

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM