匿名函数作为回调

时间:2016-08-28 23:43:52

标签: javascript anonymous-function

我正在寻求帮助,理解为什么我在使用匿名函数的方式在某些情况下会出错。

在下面的代码片段中,我使用了稍后调用的函数来填充2个数组。

var arr1 = [];
var arr2 = [];

// callback function
var func = function(i){
    return function(){$("body").append(i);}
};

var i = 1;
while(i <= 5)
{
    arr1.push(function(){$("body").append(i);});
    arr2.push(func(i));
  i++;
}

// invoke functions
$("body").append("Output from arr1 == ");
for(var c = 0; c < arr1.length; c++){ arr1[c](); }
$("body").append("<br> Output from arr2 == ");
for(var c = 0; c < arr1.length; c++){ arr2[c](); }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

现在,我想我理解为什么arr1输出66666,因为在调用时i == 6并且因为它在该函数中没有被存储为param。创作,i保留了它的最后一个已知值?

真的不明白为什么我收到TypeError: arr2[c] is not a function当我将回调函数更改为:

var func = function(i){
    $("body").append(i);
};

为什么会发生这种情况,这是实现此功能的最合适/最优雅的方式。

1 个答案:

答案 0 :(得分:0)

对于问题的第一部分,你是对的,它将保留最新的已知值。为避免这种情况,您需要使用closure。例如:

(function(x) {
   arr2.push(func(x));
})(i);

关闭通常可以用作“范围黑客”。在这种情况下,它只能确保注入的值是i的恒定电流值。

对于问题的第二部分,您的混淆可能是由于您插入函数的结果(即:func(i))而不是函数本身(func)。 / p>

在第一个场景中,您返回一个显式function(){...},因此您的数组将包含一个可以使用运算符“()”调用的函数。

在您返回$(<...>).append()的第二个方案中,不再保证您的返回值是函数。在这种情况下,结果是“jQuery”(参见:jQuery append)而不是函数,因此错误是正确的。您不能将该值用作函数。

唯一的出路是:

arr2.push(func);

然后:

arr2[c](c);

或者可能是这样:

(function(x){
    arr2[x](x);
})(c);

如果需要,在假设正确之前始终console.log填充数组内部的内容会很有帮助。由于Javascript不是一种打字语言,你可能会在怀疑有任何错误之前停留一段时间,因为它似乎按预期工作

希望这有帮助!