JS中命名和匿名回调函数之间的区别

时间:2014-06-27 04:54:48

标签: javascript function callback

我编写了以下练习代码来比较命名和匿名回调函数之间的差异,但命名回调函数抛出错误,我想知道为什么以及使用命名回调函数的正确方法。谢谢你看

friends = ["John", "Mike", "Resch", "Tony"];

friends.forEach(function(value, index) {
  console.log('index of ' + index + ', value is: ' + value);
});

function iterate(value, index)
{
  console.log('index of ' + index + ', value is: ' + value);
}

friends.forEach(iterate(value, index));

2 个答案:

答案 0 :(得分:2)

最后一行应该是:

friends.forEach(iterate);

这会传递functioniterate本身,以便.forEach()可以调用它并为其参数valueindex提供参数。< / p>

通过在其后面加上附加括号,实际上会立即调用iterate,并且会(尝试)将forEach()的返回值(默认为undefined)传递给它。

错误可能是因为valueindex不存在于iterate()之外。


为了比较,相当于:

friends.forEach(iterate(value, index));
带有匿名函数的

将是:

friends.forEach(function(value, index) {
  console.log('index of ' + index + ', value is: ' + value);
}(value, index));

答案 1 :(得分:0)

  

[JS]中命名和匿名回调函数之间的区别[

]

非常少(不包括其他答案中指出的代码错误)。

假设:

var data = [ ... ];

function foo(value, key, object){ /* do stuff */ }

然后从迭代器的角度来看,之间没有区别:

data.forEach(foo);

data.forEach(function (value, key, object){ /* do stuff */ });

在这两种情况下, forEach 都会传递对函数对象的引用。它不知道函数的名称,也不关心它只是调用它并传递所需的值。

因此,从 forEach 的角度来看,使用带或不带名称的函数表达式声明或初始化函数并不重要,结果是相同的。

回调内部存在差异。因为在第二种情况下,函数表达式中没有提供名称,所以它只能使用 arguments.callee 引用自身(比如递归),这是一些不喜欢的,在严格模式下不可用。

修复方法是使用声明的函数(如上面的第一个示例)或具有名称的函数表达式:

data.forEach(function foo (value, key, object){ /* foo references function */ });

后者意味着(在符合ECMA-262标准的浏览器中)名称仅在函数内可用。但是,IE 8及更低版本使命名函数表达式命名为全局对象的属性(或多或少全局变量),因此通常避免使用它们:

(function foo(){}());

alert(typeof foo);  // function in IE 8 and lower
                    // undefined in compliant browsers

当然,在迭代器中使用递归函数很少见(但可能并非闻所未闻)。