为什么我需要在node.js中写回“function(value){return my_function(value);}”作为callback?

对JS来说是全新的,所以请原谅,如果这是令人难以置信的明显。

假设我想用一个映射string – > bool的函数f来过滤string列表。 这工作:

filteredList = list.filter(function(x) { return f(x); }) 

这失败了:

 filteredList = list.filter(f) 

为什么???

代码示例:

  ~/projects/node (master)$ node > var items = ["node.js", "file.txt"] undefined > var regex = new RegExp('\\.js$') undefined > items.filter(regex.test) TypeError: Method RegExp.prototype.test called on incompatible receiver undefined at test (native) at Array.filter (native) at repl:1:8 at REPLServer.self.eval (repl.js:110:21) at Interface.<anonymous> (repl.js:239:12) at Interface.EventEmitter.emit (events.js:95:17) at Interface._onLine (readline.js:202:10) at Interface._line (readline.js:531:8) at Interface._ttyWrite (readline.js:760:14) at ReadStream.onkeypress (readline.js:99:10) > items.filter(function(value) { return regex.test(value); } ) [ 'node.js' ] > 

你正在传递一个对“testing”函数的引用,但是当它被调用的时候,正则expression式对象将不会被使用。 换句话说,在“testing”里面, this值是undefined

你可以避免:

 items.filter(regex.test.bind(regex)) 

.bind()方法将返回一个总是以“regex”的值运行的函数。

你经常做不到的原因是用作方法的函数不是简单的方法。 如果你使用它们而没有把它们作为方法调用,那么它们就会脱离原来的上下文。 你可以用Function.prototype.bind解决这个问题:

 items.filter(regex.test.bind(regex));