回调函数也被称为高阶函数吗?

3
我正在尝试理解回调函数和高阶函数,但是有一篇博客文章《了解JavaScript回调函数并使用它们》描述让我感到困惑,其中的暗示是它们是相同的:

回调函数,也称为高阶函数,...

这段描述在Quora上一个问题的回答中“JavaScript中高阶函数和回调函数的简单解释”被逐字重复。
我不明白这段描述。据我所知,一个高阶函数会接收或返回其他函数,而一个回调函数则是被传递/接收的函数,那么如何同时成为两者呢?是否有关于该描述我没有理解的地方?

3
我会采用维基百科的定义 - 该文章似乎错误地使用了这个术语。 - lemieuxster
许多人会混淆这些概念,因为它们非常相似。 - Barmar
1
@zfrisch 不,闭包的工作原理与定义"回调函数"和"高阶函数"这些术语并无关联。 - Bergi
@zfrisch,接下来我要看闭包 :) - thuynt13
1
@Bergi,我没意识到其他人在评论中也提到了这一点。但现在似乎我甚至无法访问这篇文章了... - thuynt13
显示剩余3条评论
3个回答

6

回调函数

回调函数是作为参数传递到另一个函数中的函数,然后在外部函数内部调用以完成某种例程或操作。

返回函数

返回函数的函数称为高阶函数。

回调函数不是高阶函数,除非它是一个返回函数的函数。

简单回调:

function toto(callback){
  /** some routine or action before */
  callback();
}

function foo(){
  console.log("I'm a simple callback");
}

toto(foo);

简单的高阶函数

function toto(){
  console.log("I'm a simple Higher-Order Function")
  return function(){
     console.log("I'm the return function");
  }
}

//first log
const func = toto();
//second log
func();

回调函数也是高阶函数:

function toto(callback){
  /** some routine or action before */
  const func = callback();
  func();
}

function foo(){
  console.log("I'm a callback and Higher-Order function");
  
  return function(){
    console.log("Do something...");
  };
}

toto(foo);


1
谢谢你的例子!它绝对澄清了混乱的解释,即回调函数可能是高阶函数,但它们不一定是相同的。 - thuynt13

2
不,回调函数不一定是高阶函数。但它们可以是高阶函数。你可以有一个回调函数来接受另一个函数作为参数。
回调函数被传递给高阶函数,这可能会导致混淆。接受另一个函数作为参数的函数是被分类为高阶函数的标准之一。

1
在我看来,高阶函数是指接受另一个函数并使用它来抽象出某些行为的函数,例如这个C#扩展方法:
    public static IEnumerable<T> OrderByProperty<T>(this IEnumerable<T> items, Func<T, object> selector)
    {
        return items.Select(x => new { o = selector(x), item = x })
                    .OrderBy(x => x.o)
                    .Select(x=> x.item);
    }

它需要一个函数来确定在排序集合时考虑哪个属性。使用示例:

    var orderedByA = Enumerable.Range(0, 100)
          .Select(x=> new Item{
            A = x,
            B = 100 - x
          })
          .OrderByProperty(x => x.A);

回调函数则可以在需要执行异步或长时间操作时用于继续应用程序流程,例如。
void FirstAsync(){
    Task.Run(()=>{
        Thread.Sleep(1000);
        Console.WriteLine("First executed");
    });
}

void Second()
{
    Console.WriteLine("Second executed");
}

void FirstV2(Action callback)
{
    Task.Run(() =>
    {
        Thread.Sleep(1000);
        Console.WriteLine("First executed");
        callback?.Invoke();
    });
}

void Main()
{
    FirstAsync();
    Second();
    Thread.Sleep(2000);
    FirstV2(Second);
}

上面程序的输出将会是这样的:
Second executed
First executed
First executed
Second executed

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接