为什么传递给替换的函数没有括号

时间:2013-09-26 18:02:45

标签: javascript regex

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

来自MDN

function replacer(match, p1, p2, p3, offset, string){
  // p1 is nondigits, p2 digits, and p3 non-alphanumerics
  return [p1, p2, p3].join(' - ');
};
newString = "abc12345#$*%".replace(/([^\d]*)(\d*)([^\w]*)/, replacer);

6 个答案:

答案 0 :(得分:2)

如果添加了括号,则会评估名为replacer的函数表达式。

而是在这里你传递一个名为replacer的变量,它是对函数的引用。您可以告诉Javascript的replace稍后使用它,而不是立即执行该功能

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

答案 1 :(得分:0)

这里有一些细微差别,一开始可能难以掌握。

如果要添加括号,则表示您希望在那时和那里调用replacer。这实际上并不是你想要做的。

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

答案 2 :(得分:0)

因为当你使用括号f()的函数名时,你要调用函数并使用结果。当你使用不带括号f时,如果意味着你正在使用函数本身。如果它有帮助,可以考虑使用它来引用函数的代码,而不是它返回的值。

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

答案 3 :(得分:0)

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

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

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

函数本身正在传递给replace的调用。 (这可能会在内部执行该功能,至少在某些条件下。)如果括号添加如下:

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

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

答案 4 :(得分:0)

这是callback

如果您致电replacer(),您将运行没有参数的replacer function

在这种情况下,替换函数要求callback as the second parameter,并且replace方法将调用给定的可调参数本身。

这样想,你可以在替换功能中做这样的事情:

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

不是像这样定义一个闭包,而是告诉替换函数调用replacer函数。

答案 5 :(得分:0)

原因是因为replacer是一个函数指针。正如您可以指向变量实例一样,您可以拥有指向函数的指针。如果在replacer之后放置了括号,例如replacer(),那么replacer将被评估为函数本身。相反,你正在做的是传递一个指向函数replacer的指针,然后函数replace可以调用它。

在c ++中:这种模式的替代方法的常见用途是函数对象/函数指针。其中struct / object使operator()重载以使其像函数一样运行。但是大多数语言都有这些版本的版本,无论它们被称为仿函数,回调,函数指针等等。