我编写了以下练习代码来比较命名和匿名回调函数之间的差异,但命名回调函数抛出错误,我想知道为什么以及使用命名回调函数的正确方法。谢谢你看
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));
答案 0 :(得分:2)
最后一行应该是:
friends.forEach(iterate);
这会传递function
,iterate
本身,以便.forEach()
可以调用它并为其参数value
和index
提供参数。< / p>
通过在其后面加上附加括号,实际上会立即调用iterate
,并且会(尝试)将forEach()
的返回值(默认为undefined
)传递给它。
错误可能是因为value
和index
不存在于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
当然,在迭代器中使用递归函数很少见(但可能并非闻所未闻)。