所以我有些困惑,我正在解决freeCodeCamp上的一个挑战。
该挑战如下
一切都是真实的
检查谓词(第二个参数)在集合的所有元素(第一个参数)上是否为真。
解决了,但是我不明白为什么我必须采取额外的步骤。我的代码是这样的:
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");
Run Code Online (Sandbox Code Playgroud)
因此在这种情况下,它应该会失败,因为其中的第二个元素collection没有该sex属性。如果pre参数(在这种情况下sex不是真值)也将失败。
当这些被击中时(我可以通过控制台日志告诉它们),但我认为它会跳出循环并从truthCheck函数中返回.....但是没有,最终它将返回真正。
我可以通过定义一个变量,然后将该值设置为false并在最后返回该变量来规避此问题。有没有更好的办法?似乎这些返回应该突破该truthCheck功能?我想念什么吗?
您不能从 ForEach 循环返回任何内容。它会undefined默认返回。
作为官方文档,Array.prototype.forEach() - JavaScript | MDN说:
除了抛出异常之外,没有办法停止或中断 forEach() 循环。如果您需要这种行为,则 forEach() 方法是错误的工具,请改用普通循环。如果您正在测试谓词的数组元素并需要布尔返回值,则可以使用 every() 或 some() 代替。
所以你可以使用一个非常简单的 for..in 循环,例如:
for(var c in collection){
// Do whatever you want
}
Run Code Online (Sandbox Code Playgroud)
正如其他答案所解释的那样,这是没有意义的:
collection.forEach(function () {
// do something
return false;
});
Run Code Online (Sandbox Code Playgroud)
因为array#forEach根本不关心其worker函数的返回值。它只是为每个数组元素执行worker函数。
您可以使用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;
}
Run Code Online (Sandbox Code Playgroud)
但是有更好的方式表达这一点。
检查谓词(第二个参数)在集合的所有元素(第一个参数)上是否为真。
可以这样解释:“ 集合的每个元素在特定的键上都有真实的价值。”
function truthCheck(collection, pre) {
return collection.every(function (elem) { return elem[pre]; });
}
Run Code Online (Sandbox Code Playgroud)
可改写为“ 无集合的元件具有在特定密钥的falsy值(或者完全丢失,密钥)”。
或者,由于Array#none实际上不存在方法,因此“ 集合中的某些元素在特定键上没有伪造的值”。
function truthCheck(collection, pre) {
return !collection.some(function (elem) { return !elem[pre]; });
}
Run Code Online (Sandbox Code Playgroud)
使用的优点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;
}
Run Code Online (Sandbox Code Playgroud)
由于undefined当您访问未设置的键时JS对象只是返回,因此hasOwnProperty此处的检查是多余的。
小智 5
[collection].forEach 的 javascript 不像普通循环那样工作。除非你让它抛出异常,否则没有办法提前结束它。
您期望的行为是您对 javascript for 循环的期望,但由于 forEach 为每个循环对象使用回调函数,因此您只退出回调函数而不是 forEach。另外值得注意的是,在您的代码中,您有一个 for 循环,其中有一个返回值。这个循环中的 return 块只会中断这个循环,而不是 forEach(我之前提到过,除非另有说明,否则不能过早终止)
如您所见,forEach 主要用于迭代所有元素,而不是对每个迭代元素进行条件检查。
| 归档时间: |
|
| 查看次数: |
8607 次 |
| 最近记录: |