JavaScript中的回调函数(附代码示例)

68 阅读3分钟

函数是JavaScript中的第一等公民。这就是为什么你很早就会听到JavaScript中的回调函数,它是编写JavaScript代码时的一个超级强大的资产。在这里,我想给大家简单介绍一下它们。

回调函数通常作为参数传递给函数:

function printText(text, fn) {
  ...
}

printText('do something', function printSomethingElse() {
  console.log('do something afterward');
});

在这个例子中,我们的printText 函数需要两个参数:一个文本和一个回调函数。回调函数是作为一个内联函数传递给printText 。你也可以在传递给printText 之前,将其作为一个函数声明提取:

function printText(text, fn) {
  ...
}

function printSomethingElse() {
  console.log('do something afterward');
}

printText('do something', printSomethingElse);

这两种方式都可以。现在,不管我们传递给printText 函数的文本是什么,我们希望最终在我们的printText 函数中的某个地方执行回调函数,因为否则我们就不会把它传递进去:

function printText(text, fn) {
  console.log(text);

  fn();
}

function printSomethingElse() {
  console.log('do something afterward');
}

printText('do something', printSomethingElse);

这可能是接收我们回调函数的printText 函数的一种实现方式。在这种情况下,它将首先打印*"做某事",然后"之后做某事"*。你如何实现所有这些函数,完全取决于你。这更多的是关于作为参数传递给printText 函数的函数,以及在这个函数中用于在某个点上被调用。

从本质上讲,一个回调函数被用于另一个函数中,最终被执行。这个另一个函数决定什么时候执行这个函数,以及它向这个函数传递哪些参数。

例如,让我们创建一个通用的过滤器函数,根据一个回调函数过滤一个JavaScript数组:

function filter(list, filterFn) {
  let newList = [];

  for (let i = 0; i < list.length; i++) {
    const item = list[i];

    if (filterFn(item)) {
      newList.push(item);
    }
  }

  return newList;
}

该函数接收一个数组作为第一参数,接收一个回调函数作为第二参数。当函数本身在数组上迭代时,它拉出数组中的每一个项目并将其传递给回调函数。如果回调函数返回true,则该项目被添加到过滤的列表中。如果回调函数返回false,它就不会被添加到过滤后的列表中。

这里最关键的一点是,过滤器函数不知道任何用于将项目添加到列表中的条件。它只知道它根据来自外部的一些条件(回调函数)来过滤一个数组。现在,我们可以通过以下方式使用这个通用的过滤函数:

const result = filter([3, 6, 1], function greaterThanFive(item) {
  return item > 5;
});

console.log(result);
// [6]

如前所述,你可以把回调函数作为参数内联,也可以在外部声明它:

function greaterThanFive(item) {
  return item > 5;
}

const result = filter([3, 6, 1], greaterThanFive);

console.log(result);
// [6]

重要的事实是,作为使用过滤函数的开发者,我们决定在这里应用哪个过滤条件。从这里开始,使用JavaScript的内置过滤器就不远了,它可以在JavaScript数组上使用:

const result = [3, 6, 1].filter(function greaterThanFive(item) {
  return item > 5;
});

console.log(result);
// [6]

这个函数的行为和我们之前自己实现的一样,因为它需要一个回调函数,这个回调函数也会评估过滤条件。唯一不同的是,它已经作为一个方法内置在JavaScript数组中了。

对于所有这些情况,你也可以使用匿名的JavaScript回调函数,如果它们是内联的:

const result = [3, 6, 1].filter(function (item) {
  return item > 5;
});

此外,你还可以使用JavaScript箭头函数,以保持你的回调函数更加简洁:

const result = [3, 6, 1].filter((item) => item > 5);

console.log(result);
// [6]

总之,回调函数很强大。以回调函数为参数的函数可以保持相当的通用性,因为使用这个函数的开发者必须在回调函数中定义关键行为。