Javascript 为什么传递给replace的函数没有括号

Javascript 为什么传递给replace的函数没有括号,javascript,regex,Javascript,Regex,为什么将函数传递给replace的最后一个参数时,该函数不带括号 发件人: 这里有一点细微差别,一开始可能很难把握 如果要添加括号,则表示希望立即调用replacer。那不是你真正想做的 replace实际上是在寻找一个函数的引用,因此实际上是将函数作为参数传递给replace。在内部,replace知道何时何地正确调用replacer如果添加了括号,则将计算名为replacer的函数表达式 相反,这里传递的是一个名为replacer的变量,它是对函数的引用。不是立即执行函数,而是告诉Javas

为什么将函数传递给
replace
的最后一个参数时,该函数不带括号

发件人:


这里有一点细微差别,一开始可能很难把握

如果要添加括号,则表示希望立即调用
replacer
。那不是你真正想做的


replace
实际上是在寻找一个函数的引用,因此实际上是将函数作为参数传递给
replace
。在内部,
replace
知道何时何地正确调用
replacer

如果添加了括号,则将计算名为
replacer
的函数表达式

相反,这里传递的是一个名为
replacer
的变量,它是对函数的引用。不是立即执行函数,而是告诉Javascript的
replace
稍后在本机调用时使用它


我有时会想到一个比喻,你把枪交给别人开枪,而不是你自己开枪
replacer()
表示“立即开火”,而
replacer
表示“在这里,用这个开火”。这里的期望是JavaScript的本机
replace()
函数将使用子弹(参数)来“加载枪”,然后在准备就绪时发射

因为当使用带括号的函数名f()时,需要调用函数并使用结果。如果不带括号使用,f,if表示您正在使用函数本身。如果有帮助的话,可以将其视为您想要引用函数的代码,而不是它返回的值


在您的示例中,您没有调用函数replacer并传递要替换的值。您正在将一段名为replaced的代码传递给函数replace,以便函数replace在需要时调用它。

在JavaSCript中,函数与其他函数一样是一个对象。它可以分配给变量、传递给函数、从函数返回等等

在这种情况下,
replacer
的引用被用作变量:

newString = "abc12345#$*%".replace(/([^\d]*)(\d*)([^\w]*)/, replacer);
函数本身被传递到对
replace
的调用中。(至少在某些情况下,它可能会在内部执行该函数。)如果括号是这样添加的:

newString = "abc12345#$*%".replace(/([^\d]*)(\d*)([^\w]*)/, replacer());

然后将函数的结果作为参数传递,而不是将函数本身作为参数传递。该函数的结果似乎是一个字符串。但是,您调用的函数不需要字符串,它需要函数。(当它试图“执行”该字符串时,向其传递字符串可能会失败。)

这是一个
回调

如果调用
replacer()
,则运行的是
replacer函数
,没有任何参数

在这种情况下,replace函数要求将
回调作为第二个参数,replace方法将调用给定的可调用参数本身

这样想,您可以在replace函数中执行以下操作:

.replace(/([^\d]*)(\d*)([^\w]*)/, function() {
    //You can write replacer's code here as a closure
});

不是这样定义闭包,而是告诉replace函数调用replacer函数。

原因是
replacer
是函数指针。正如可以有指向变量实例的指针一样,也可以有指向函数的指针。如果括号放在
replacer
之后,例如
replacer()
,则
replacer
将作为函数本身进行计算。相反,您要做的是传递一个指向函数
replace
的指针,然后函数
replace
可以调用该函数


在c++中:这种模式的另一种常见用法是函数对象/函数指针。其中struct/对象重载了操作符(),使其像函数一样工作。但是大多数语言都有这样的版本,不管它们被称为functor、callback、函数指针还是其他什么。

这与向函数传递引用相反。我认为OP的困惑在于replacer需要参数,而回调似乎不发送参数。只是一个猜测,因为当我第一次看到这个的时候,我很好奇。@KaiQing:可能。虽然我们看不到调用
replacer
的位置,但我们看不到它是否正在接收参数。在本例中,我假设
replace
在内部将它们提供给回调。@KaiQing是的,就是这样。它是如何获得这些参数的?@thomas:当它在
replace
中被调用时,调用它的行正在发送它需要的参数。您所做的只是告诉代码
replace
调用哪个函数,它实际处理调用它的过程。(您可能可以查看
replace
的源代码,无论其定义在哪里,都可以查看。)
.replace(/([^\d]*)(\d*)([^\w]*)/, function() {
    //You can write replacer's code here as a closure
});