将函数数组作为参数传递

3

这是我的代码:

function test(e, f) {
    for (var i = 0; i < e.length; i++) {
        $('#clickme').append("<button id='op" + i + "'>" + e[i] + "</button>")
        $('#op' + i).click(function () {
            f[i]();
        })
    }
}


$(function postPunk() {
    var func1 = function () {
        alert('1');
    }
    var func2 = function () {
        alert('2');
    }
    var func3 = function () {
        alert('3');
    }
    test(['Option1', 'Option2', 'Option3'], [func1, func2, func3]);
})

点击事件没有调用函数。如果我在点击事件中放置一个警报测试,它可以正常触发。

有什么想法,为什么这不起作用? 这似乎是将函数数组作为参数传递的问题。有更好的方法吗?


2
不知道在 JavaScript 中分号是可选的。你在第6行和最后一行都漏掉了它们。 - huysentruitw
请查看上述问题。这可能会对您有所帮助。 - Ramaraj Karuppusamy
有更多的“丢失”的分号 ;,比如每个函数表达式。它们是“可选的”,但最好不要省略它们。 - Jared Farrish
1
@WouterH 在 JavaScript 中,大多数情况下都可以省略显式分号(对于已经使用每行一个语句编写的干净代码)。这不会对上面的代码造成任何问题。查找“ASI”(自动分号插入)以了解规则。我在 JavaScript 中几乎不写分号;了解规则并保持一致。 - user166390
@pst - 这正是我认为养成这种习惯是一个“最佳实践”的原因,直到他们更好地了解规则为止。从语法上讲,我认为首先学习严格模式更好,然后再决定使用不同选项的舒适水平。我同意,盲目遵循规则是过于简单化了。但在学习过程中推迟结束语句并不是错误的做法。(另外,在 jsFiddle 中这样做会破坏Tidy Up...) - Jared Farrish
显示剩余4条评论
4个回答

8

和其他类似问题一样,i会不断变化。

相反,尝试这样做:

for( var i=0; i<e.length; i++) {
    (function(i) {
        // your code that depends on i not changing
    })(i);
}

1
@JaredFarrish 不,因为 f 不像 i 一样会改变。 - Niet the Dark Absol

4

看起来这是经典的JavaScript问题,因为它们都是最后一个值(或者是undefined,因为f[3]不存在),因为这是循环结束后i的值。

尝试将函数引用直接传递给click处理程序。

function test(e, f) {
    for (var i = 0; i < e.length; i++) {
        $('#clickme').append("<button id='op" + i + "'>" + e[i] + "</button>")
        $('#op' + i).click(f[i])
    }
}

或者,另一种解决方案是创建一个返回函数的函数。这将允许它“关闭”i
function test(e, f) {
    var makeFunc = function(i) {
        return function() {
            f[i]();
        }
    };
    for (var i = 0; i < e.length; i++) {
        $('#clickme').append("<button id='op" + i + "'>" + e[i] + "</button>")
        $('#op' + i).click(makeFunc(i))
    }
}

2
+1 直接将函数传递给 .click。如果不需要 i,这是唯一明智的解决方案。 - Felix Kling

1
回调函数中的代码在循环结束后使用了i的值,因此它指向数组之外的索引。您需要在循环中使用闭包,以便每次迭代都获得其自己的变量实例:
function test(e, f) {
  for (var i = 0; i < e.length; i++) {
    $('#clickme').append("<button id='op" + i + "'>" + e[i] + "</button>");
    (function(i){
      $('#op' + i).click(function () {
        f[i]();
      });
    })(i);
  }
}

0

这是我让它工作的方法:http://jsfiddle.net/fH2Dk/3/

function test(e, f){    
     for(var i = 0; i < e.length; i++) {
         (function(i) {
            $('#clickme').append("<button id='op" + i + "'>" + e[i] + "</button>");
            $('#op' + i).click(function(){
                f[i]();
            });
        })(i);    
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接