3

我有一个变量 'fieldCount' 等于 5(我拥有的字段数)。如何在不具体说明每个索引的情况下写出以下内容:

if (
   fields[0].checkValidity() && fields[1].checkValidity() && fields[2].checkValidity()
   && fields[3].checkValidity() && fields[4].checkValidity()
) {
    fieldsPass = true;
}
4

5 回答 5

4

您可以使用循环或一些相当标准的内置浏览器功能。

环形

这是使用循环的方法。这应该是最快的代码,但您可能不需要最快的代码,除非您要检查大量项目的大量字段。我建议改为“正确、清晰、简洁、快速”的优先级,因此认为您应该从内置浏览器功能开始。但这里仅供参考:

var fieldsPass = true;
var i, l = fields.length;
for (i = 0; i < l; i += 1) {
   if (fields[i].checkValidity()) continue;
   fieldsPass = false;
   break;
}

请注意,在循环外声明i变量并在循环外捕获字段长度是可选的。

我第一次这样做是因为很多人不知道提升,并且for (var i ...不创建仅在循环内可用的变量这一事实,它与在函数顶部for声明相同,并且这种行为可能导致错误var i.

第二个我是出于习惯,尽管正如我所说,你可以把它放在循环检查中。请参阅此讨论。如果您确实使用循环方法,您可能正在寻找更好的性能,因此可能希望使用捕获的长度方式以获得最佳性能。(如果它真的那么重要,你可以做这个var i = fields.length; while (i--) { }方法。)

浏览器函数数组.Every

您可以使用Array.prototype.every()(来自 ECMAScript 2015 第 6 版):

Mozilla 开发者网络

every() 方法测试数组中的所有元素是否通过提供的函数实现的测试。

fieldsPass = fields.every(function(field) {
   return field.checkValidity();
});

true当传入的函数在数组中的每个项目上运行时,它返回true所有这些项目。如果任何一个返回false,它就会停止并返回false。如果您熟悉的话,在某些语言中,他们将同一个概念称为all 。

或者,最好只声明checkValidity一次函数,而不是将其放在每个字段上。这可能是不可能的,这取决于您如何实现它(也许它可以访问私有变量?)。请注意,您提供的回调函数的第一个参数(请参阅上面链接中的文档)是currentValue迭代的​​,您要检查的字段。如果您的函数看起来像这样,它将起作用:

function checkValidity(field) { /* check validity */ }

fieldsPass = fields.every(checkValidity);

浏览器函数数组.Some

您还可以使用Array.prototype.some()(来自 ECMAScript 2015 第 6 版):

Mozilla 开发者网络

some() 方法测试数组中的某个元素是否通过了提供的函数实现的测试。

fieldsPass = !fields.some(function(field) {
   return !field.checkValidity();
});

请注意,它基本上只是 的倒数every,因为“ALL VALID”与“NOT (ANY INVALID)”相同。它只是意味着它检查数组中传递函数的任何一项,如果是,则返回true。在某些语言中,如果您熟悉的话,他们将相同的概念称为any 。

一般浏览器兼容性说明

请注意,对于这两个功能,浏览器兼容性非常好。如果您不关心版本 9 以下的 IE,那么您非常安全。如果你这样做了,那么你会想要使用上面链接的 MDN 页面上提供的 polyfill。您可以将该代码包含在您的 javascript 文件的全局范围内,然后就可以在 IE 8 及更低版本中正常使用它。(我说的是这样开始的代码块:)

if (!Array.prototype.every) {
   Array.prototype.every = function(callbackfn, thisArg) {
   ...
}
于 2016-12-02T22:22:08.620 回答
3

您有一个字段数组,并且您想要迭代它们,并对它们中的每一个调用有效性检查方法。只有当他们都通过时,标志fieldsPass才会是true

这正是 的行为Array#every。根据 MDN:

every() 方法测试数组中的所有元素是否通过提供的函数实现的测试。


用于在每个字段Array.every上调用。checkValidity()如果所有字段都有效,则结果将为true. 如果一个字段失败checkValidity(),则循环将false立即返回,而不检查其他字段。

var fieldPass = fields.every(function(field) {
  return field.checkValidity();
})
于 2016-12-02T21:42:51.117 回答
2

就像你说的,使用循环。

var fieldsPass = true;
for (var i = 0; i < fields.length; i++) {
  // Exit early if one of them fails
  if (!fields[i].checkValidity()) {
    fieldsPass = false;
    break;
  }
}
于 2016-12-02T21:43:11.570 回答
1

您可以使用该.some()方法并反转逻辑来判断是否全部通过,如下所示:

var allPassed = !fields.some(function (field) {
  return !field.checkValidity();
});
于 2016-12-02T21:43:43.623 回答
1

你可以这样做:

fieldsPass = true;
for (i = 0; i < fieldCount; i++)
{
     if(!fields[i].checkValidity())
     {
          fieldsPass = false;
          break;
     }
}
于 2016-12-02T21:45:17.973 回答