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

问题描述 投票:0回答:3

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

假设我想使用映射 string -> bool 的函数 f 来过滤字符串列表。这有效:

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' ]
> 
javascript node.js callback
3个回答
27
投票

您正在传递对“test”函数的引用,但是当它被调用时,正则表达式对象将不会出现。换句话说,在“test”中,

this
的值将是
undefined

你可以避免这种情况:

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

.bind()
方法将返回一个函数,该函数始终以“regex”的值为
this
运行。


8
投票

您经常无法做到这一点的原因是用作方法的函数不仅仅是方法。如果您使用它们而不将它们作为方法调用,那么它们就会脱离其原始上下文。您可以使用

Function.prototype.bind
来解决这个问题:

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

6
投票

正如其他人所说,调用函数引用时,

this
undefined
。我想提供一个非反射性的、稍微冗长的替代方案:

items.filter(RegExp.prototype.test.bind(/regex/g));
© www.soinside.com 2019 - 2024. All rights reserved.