所以我有点困惑,我正在解决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#every
或Array#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;
}