array.prototype.every() 具备短路特性,首个校验失败即终止执行,适用于表单全量校验;需用纯函数封装各字段规则,配合命名对象可定位首个错误字段;禁用异步操作与副作用,避免状态不一致。

Array.prototype.every() 天然具备短路特性:一旦某个回调返回 false,它立刻停止遍历,不再执行后续校验。这正适合表单全量校验中“发现第一个非法字段就终止、避免无谓计算”的需求。
构建校验规则数组,每项返回布尔值
将每个字段的合法性检查封装为独立函数,统一放入数组。每个函数只关注自身逻辑,输入字段值,输出 true(合法)或 false(非法)。
例如:
() => name && name.length >= 2() => /^\S+@\S+\.\S+$/.test(email)() => password === confirmPwd
用 every() 依次执行并利用短路机制
调用 rules.every(fn => fn())。只要任一校验函数返回 false,every() 立即返回 false,后续函数不会被调用——这就是短路保护的核心表现。
注意:所有校验函数必须是**无副作用的纯函数**(不修改外部状态、不发请求、不弹窗),否则短路可能导致部分副作用未触发,造成逻辑错乱。
配合错误收集,实现“短路执行 + 错误定位”
若还需知道是哪个字段出错,可在规则数组中使用带名称的对象,结合索引提前退出:
const rules = [
{ field: 'name', check: () => name && name.length >= 2 },
{ field: 'email', check: () => /^\S+@\S+\.\S+$/.test(email) },
{ field: 'password', check: () => password.length >= 6 }
];
let firstError = null;
const isValid = rules.every(({ field, check }, i) => {
if (!check()) {
firstError = field;
return false; // 主动中断
}
return true;
});
// isValid 为 false 时,firstError 即首个失败字段名
避免常见陷阱
不要在 every() 回调里做异步操作(如 await api.validate()),因为 every() 不支持 Promise,且无法对异步调用实现真正短路。如需异步校验,应改用 for...of 循环 + await + break。
也不要依赖 every() 的返回值来判断“是否全部通过”,却在回调中修改共享变量——短路会让部分修改失效,导致状态不一致。










