在 Underscore JS 中编写我的 _.reject 版本

Writing my version of _.reject in Underscore JS

  // Return all elements of an array that pass a truth test.
  _.filter = function(collection, test) {
    var result = []; //make a result variable 
    //iterate over the collection array using _.each
    _.each(collection, function(value) {
    //if conditions for test(element) = positive
      if (test(value)) {
        //push element into result
        result.push(value);
      }
    });
    return result;
  };

您好,我正在重写 Underscore JS 库中 _.filter & _.reject 的函数。我仍然对回调函数感到有点困惑,尤其是当同一个函数中有这么多回调函数时。我需要在这里澄清一下我的想法和逻辑;特别是关于 ._reject。我正在重用我的 _.filter 函数并在我的 _.reject 函数中实现它。

 _.reject = function(collection, test) {
    return _.filter(collection, function(value) {
      return !test(value);
    })
  };

当我将函数(值)作为过滤器的参数并定义它时;是用那个函数回调替换我的测试值吗?特别是在这一行 - if (test(value)) {... 在这种情况下是否会被我的回调所取代 if(function(value) {return !test(value)}) 另外,如果我从我的 _.reject 函数中省略 _.filterreturn 命令;我只是返回函数本身吗?抱歉 - 我知道这有点奇怪,因为据我所知我的代码可以正常工作,但实际上更多的是尝试尝试然后从逻辑上真正理解它。当我从我的拒绝函数

中调用过滤器中的回调函数时,我对会发生什么感到非常困惑

在 JavaScript 中,一切都是对象——包括函数。当你像这样写一个函数表达式(他们这样称呼)时:

const foo = function() {
  console.log('This function prints this message!');
};

foo 现在包含对打印消息的函数的引用。我们可以这样称呼它:

foo();

…其中 运行 是代码并打印消息。您可以像任何其他值一样传递 foo,包括作为其他函数的参数。把它想象成保存一组做某事的指令:你告诉计算机“foo 包含代码,当 运行 时,它会打印一条消息。”

在您的示例中,您作为第二个参数传递给 _.filter 的函数表达式是一个对象:

function(value) {
  return !test(value);
}

你是说 "Pass this function—which takes a value, calls test with it, negates the result, and returns it—to my _.filter function." _.filter 知道调用 that 函数来过滤值。

编程充满了这些类型的模式:目标不是查看一直发生的事情,而是要了解 _.filter 接受第二个参数,该参数是一个函数 "If you give me a value, I'll tell you whether to keep it." 在您的代码中,您向它传递了一个执行此操作的函数——但它还调用了您的用户传入的 另一个 函数 (test)。函数调用可以很长:数百或数千个函数调用其他函数。

就您而言,您的代码看起来是正确的。 _.filter 说 "Give me an array of data and a function. I'll call that function for each value in the array, and it'll return me whether to keep it." 你正在做一个说 "Give me an array of data and a function. I'll call that function for each value in the array, and it'll return me whether not to keep it." 要做到这一点的函数,你只是反转 _.filter 想知道的:而不是是否保留记录,你想知道是否消除它。

因此您的代码将用户的数组和一个函数提供给 _.filter,就像它想要的那样。数组的每个元素都会调用该函数。 _.filter想知道是否保留该项目。您将使用 _.filter 询问的项目致电 test。但是如果用户的函数 returns true,我们想要 消除 元素,而不是保留它,所以我们否定它(使用 ! ) 和 return 值。然后你 returning _.filter.

的结果

关于 return 的澄清:return 关键字告诉 调用您的函数的函数 您想要 "give back" 什么。因此,当您 return !test(value) 时,您是在告诉 调用函数 !test(value) 的值(在本例中,即 _.filter)。如果您不使用 return,您将不会向调用您的函数的代码返回任何内容。如果用户想知道在元素被拒绝后数组是什么样子,而你的函数没有return任何东西,那么你的函数不是很有用!