foreach/for..in不返回值



所以我有点困惑,我正在解决freecodecamp上的挑战。

挑战如下

一切都是true

检查谓词(第二个参数(是否在集合的所有元素上是真实的(第一个参数(。

它已经解决了,但我不明白为什么我必须额外迈出一步。我的代码就是这样:

function truthCheck(collection, pre) {
    collection.forEach(function(element) {
        for (key in element) {
            if (!element.hasOwnProperty(pre)) {
                return false;
            } else if (key === pre) {
                if (!Boolean(element[key])) {
                    return false;
                }
            }
        }
    });
    return true;
}
truthCheck([
    {"user": "Tinky-Winky", "sex": "male"},
    {"user": "Dipsy"},
    {"user": "Laa-Laa", "sex": "female"},
    {"user": "Po", "sex": "female"}
], "sex");

因此,在这种情况下,它应该失败,因为collection中的第二个元素没有sex属性。另外,如果pre参数或在这种情况下,sex不是真实的值。

当这些击中时(它们是,我可以通过控制台日志告诉(,但是我认为它会脱离循环并从truthCheck函数中返回.....但是它没有,但是它没有,并且它最终将返回true。

我能够通过定义变量,然后将该值设置为false,然后在末尾返回变量来绕过它。有没有更好的办法?这些返回似乎应该脱离truthCheck功能?我想念什么吗?

正如其他答案所解释的那样,这是毫无意义的:

collection.forEach(function () {
  // do something
  return false;
});

因为array#forEach根本不在乎其工人功能的返回值。它只是执行每个数组元素的工作函数。

您可以使用Worker函数设置外部变量:

function truthCheck(collection, pre) {
  var allAreTruthy = true;
  collection.forEach(function (elem) {
    // if this ever flips allAreTruthy to false, it will stay false
    allAreTruthy = allAreTruthy && elem[pre];
  });
  return allAreTruthy;
}

但是有更好的方法来表达这一点。

检查谓词(第二个参数(是否在集合的所有元素上是真实的(第一个参数(。

可以用作" 该集合的每个元素在特定键上具有真实值。"

function truthCheck(collection, pre) {
  return collection.every(function (elem) { return elem[pre]; });
}

可以用作" 的 在特定键处具有虚假的值(或完全缺少密钥(。"

或,由于Array#none方法实际上不存在,因此"没有集合的某些元素在特定键上具有虚假值。"

function truthCheck(collection, pre) {
  return !collection.some(function (elem) { return !elem[pre]; });
}

使用Array#some的优点是,它一旦满足了该阵列,就可以停止迭代数组。如果您的阵列有很多元素,这将意味着提高性能。对于短数组,使用Array#everyArray#forEach没有太大区别。

上面的语义等效于

function truthCheck(collection, pre) {
  var i;
  for (i = 0; i < collection.length; i++) {
    if (!collection[i][pre]) return false;
  }
  return true;
}

由于JS对象只需返回undefined,当您访问尚未设置的键时,hasOwnProperty的检查是多余的。

您无法从foreach循环中返回任何内容。默认情况下,它将返回undefined

作为官方文档,array.prototype.foreach(( - javascript |mdn,说:

除了抛出异常外,没有其他方法可以停止或打破foreach((循环。如果您需要这样的行为,则foreach((方法是错误的工具,请使用普通循环反而。如果您要测试谓词的数组元素,并且需要布尔值返回值,则可以使用每个((或某些((。

因此,您可以使用非常简单的循环,例如:

for(var c in collection){
    // Do whatever you want
} 

[collection]。除非您使其异常。

您期望的行为是您对循环的JavaScript所期望的,但是由于foreach使用每个循环对象的回调函数,因此您只会退出回调功能而不是foreach。另外,值得注意的是,在您的代码中,您有一个有返回的循环。此循环中的返回块仅破坏此循环而不是foreach(我之前提到的,除非另有说明,否则不能过早终止(

(

您可以看到foreach主要是为了迭代所有元素,而不是每个迭代元素的有条件检查。

function truthCheck(collection, pre) {
  return collection.every(function (person) { return !!person[pre]; });
}

您在集合的每个元素上执行一个函数。此功能检查元素返回某物。但是返回的值不会影响外部函数的结果。由于外部函数不取决于内部函数,因此您的结果是正确的。

如果定义一个变量,请将其设置为false,然后返回该变量的末端将有效,但效率低下。让我们考虑以下情况。您发现一个没有目标密钥的元素。所以现在您应该返回,但您不能。您必须在整个系列中努力工作。foreach循环不会让您没有一团糟的机会退出。因此,一个更好的想法是用于循环。如果找到您要寻找的东西

,您可以退出for循环

一种稍微简单的方法是:

function truthCheck(collection, pre) {
    //iterate thrugh your collection
    for (var c in collection){
        //get keys of element as an array and check if pre is in that array
        if( Object.keys(collection[c]).indexOf(pre) == -1){
            // pre was not found
            return false;
        }
    }
    return true;
}

最新更新