为什么要将整个函数定义作为参数传递,而不仅仅是可以重用的函数名称?
Why pass an entire function definition as an argument instead of just the function name which can be reused?
前者好像比JavaScript多"hip",不明白为什么。
编辑:针对这个可能重复的问题,我感兴趣的是为什么,而不是如何。另一个仅在标题中询问 "closures" 的问题不会引起尚未在此和闭包之间做出 link 的人的注意。
tl;dr:因为很多函数其实并没有被复用
我想你已经回答了你自己的问题:
... instead of just the function name which can be reused?
其中许多是 "one-off" 个案例。该行代码只执行一次,传递的函数不必重复使用。
例如,如果我想将一个事件处理程序绑定到一个 body
并且我不打算在任何地方重用该事件处理程序,我为什么要写
function bodyEventHandler() {}
document.body.addEventListener('click', bodyEventHandler);
并用 bodyEventHandler
?
不必要地污染当前作用域
document.body.addEventListener('click', function() {...});
效果相同,不污染作用域,在使用的地方保留函数定义。
JavaScript 很大程度上是事件驱动的,大多数事件处理程序实际上不会在其他任何地方重用。
在使用函数的地方保留函数定义也是 IMO 的一个常见原因。有些功能要么很简单,但是给它们取一个描述性的名字可能并不容易。
例如如果你不熟悉"pluck"这个词,你会明白什么
var names = users.map(pluck('name'));
真的吗?也许你可以从其他变量名称中推断出来。
然而,
var names = users.map(function(user) { return user.name; });
一目了然。
事实上,你会更频繁地看到这些,现在 ECMAScript 6 引入了箭头函数,就像其他语言中的 lambda 函数一样:
var names = users.map(user => user.name);
我还认为您对传递函数时到底发生了什么有误解:
... pass an entire function definition as an argument instead of just the function name ...
foo(bar)
不会将名称 "bar" 传递给 foo
。它传递由变量 bar
引用的函数对象。那和foo(function() { ... })
没什么区别。唯一的区别是我们没有(暂时)将函数存储在变量中。
前者好像比JavaScript多"hip",不明白为什么。
编辑:针对这个可能重复的问题,我感兴趣的是为什么,而不是如何。另一个仅在标题中询问 "closures" 的问题不会引起尚未在此和闭包之间做出 link 的人的注意。
tl;dr:因为很多函数其实并没有被复用
我想你已经回答了你自己的问题:
... instead of just the function name which can be reused?
其中许多是 "one-off" 个案例。该行代码只执行一次,传递的函数不必重复使用。
例如,如果我想将一个事件处理程序绑定到一个 body
并且我不打算在任何地方重用该事件处理程序,我为什么要写
function bodyEventHandler() {}
document.body.addEventListener('click', bodyEventHandler);
并用 bodyEventHandler
?
document.body.addEventListener('click', function() {...});
效果相同,不污染作用域,在使用的地方保留函数定义。
JavaScript 很大程度上是事件驱动的,大多数事件处理程序实际上不会在其他任何地方重用。
在使用函数的地方保留函数定义也是 IMO 的一个常见原因。有些功能要么很简单,但是给它们取一个描述性的名字可能并不容易。
例如如果你不熟悉"pluck"这个词,你会明白什么
var names = users.map(pluck('name'));
真的吗?也许你可以从其他变量名称中推断出来。
然而,
var names = users.map(function(user) { return user.name; });
一目了然。
事实上,你会更频繁地看到这些,现在 ECMAScript 6 引入了箭头函数,就像其他语言中的 lambda 函数一样:
var names = users.map(user => user.name);
我还认为您对传递函数时到底发生了什么有误解:
... pass an entire function definition as an argument instead of just the function name ...
foo(bar)
不会将名称 "bar" 传递给 foo
。它传递由变量 bar
引用的函数对象。那和foo(function() { ... })
没什么区别。唯一的区别是我们没有(暂时)将函数存储在变量中。