argument 参数如何为这些嵌套函数工作?

How do the argument parameters work for these nested functions?

我正在努力提高我对 Javascript 中高阶函数和回调的理解。我这里的代码给了我正在寻找的输出,但我不确定它是如何工作的。我的困惑是参数如何在 filterArray 中用于 callback 以及它如何传递给 eitherCallback实际上有两个参数:callback1callback2,它们是函数。从技术上讲,callback(在 filterArray 中)正在获取一个数字,那么它如何传递给 eitherCallback如果 eitherCallback 的两个参数存储为函数?我是 Javascript 的超级新手,非常感谢您的宝贵时间和善意。 :)

function eitherCallback(callback1, callback2) {
  return num => callback1(num) || callback2(num); 
}

function filterArray(array, callback) {
  const newArray = [];
  for (let i = 0; i < array.length; i += 1) {
    if (callback(array[i], i, array)) newArray.push(array[i]);
  }
  return newArray;
}
const arrOfNums = [10, 35, 105, 9];
const integerSquareRoot = n => Math.sqrt(n) % 1 === 0;
const over100 = n => n > 100;
const intSqRtOrOver100 = eitherCallback(integerSquareRoot, over100);
console.log(filterArray(arrOfNums, intSqRtOrOver100)); // should log: [105, 9]

让我们看看这个函数:

function eitherCallback(callback1, callback2) {
  return num => callback1(num) || callback2(num); 
}

这是 return 一个新函数,它有一个参数用于 num

所以如果我们进一步分解它:

这里是将intSqRtOrOver100赋值给上述函数的return值,确实也是一个函数。

const intSqRtOrOver100 = eitherCallback(integerSquareRoot, over100);

函数 eitherCallback 可以访问外部范围参数 (callback1, callback2),同时在调用 returned 函数时也可以访问内部范围 num 参数。 这种技术就是所谓的 Closure.

此外,Array 对象中的 javascript 中有内置函数,用于过滤、减少等。 例如 您可以直接将已声明的函数传递给它,例如

const filteredArray = arrOfNums.filter( intSqRtOrOver100 );

或者您可以在线进行:

例如

const filteredArray = arrOfNums.filter( num => ( integerSquareRoot(num) || over100(num) ) )

const filteredArray = arrOfNums.filter( num => (
  Math.sqrt(num) % 1 === 0 ||
  num > 100
) );

这里的相关点只是 eitherCallback 有两个回调(即两个函数)和 returns 另一个函数。 JavaScript 中的函数是“第一个 class” 值——这不仅意味着它们可以作为参数传递给其他函数,它们还可以从函数返回。您可以非常清楚地看到 eitherCallback returns 一个函数,它的单行带有 return 语句 - returns 是什么

num => callback1(num) || callback2(num)

这是一个函数表达式。具体来说,它是一个调用 callback1 和* callback2 以及 returns 其结果的“逻辑或”的函数。

所以给 filterArraycallback 确实需要一个数字参数。这里的函数是 eitherCallback(integerSquareRoot, over100) - 一个接受数字并告诉您它是否具有整数平方根或大于 100 的函数。

总结一下:eitherCallback 接受它传递的两个回调和 returns 另一个回调 - 这个结果回调是传递给 filterArray 的回调。如果我能说得更清楚,请告诉我。

*严格来说并不总是,因为 || 的 short-circuiting。但这并不重要,除非函数有副作用,而这里使用的函数没有

我想强调和扩展@RobinZigmond 所写的内容:

他们要理解的重点是:

(1) 当您将函数作为参数传递时,您不需要同时传递该函数所依赖的参数 - 这些参数可以稍后提供。

也许在您的 web.xml 中仔细研究以下示例。这是您上面所做的一个简化示例:

function a(someNumber){ return someNumber;}

function b(functionArgument){ return functionArgument;}

所以现在当我这样做时:

b(a)   // => function a(someNumber) // of course if I pass in `a` as an argument to the `b` function, then i will get `a` back!!

我可以将其分配给一个常量:

   const c = b(a);   // when i pass a function, I do not need to pass in the argument that a requires - which is also a number.

   c // => function a(someNumber)  // to be expected

   c(3) // => returns 3!