闭包实现表单校验器通过封装规则、错误、值等状态于函数作用域内,提供validate、addRule等方法;每个字段创建独立实例互不干扰;支持同步校验、实时DOM反馈及异步规则扩展。

用闭包实现前端表单字段校验器,核心是把校验规则、错误信息、当前值等状态封装在函数作用域内,避免全局污染,同时支持为不同字段创建独立、可复用的校验实例。
闭包校验器的基本结构
每个校验器是一个返回对象的函数,内部维护私有状态(如规则列表、是否已触发校验),对外只暴露 validate、addRule、setError 等方法:
function createValidator() {
let value = '';
let rules = [];
let errors = [];
let isTouched = false;
return {
setValue(v) { value = v; },
addRule(test, message) { rules.push({ test, message }); },
validate() {
isTouched = true;
errors = [];
for (const { test, message } of rules) {
if (!test(value)) {
errors.push(message);
}
}
return errors.length === 0;
},
getErrors() { return isTouched ? errors : []; },
isInvalid() { return isTouched && errors.length > 0; }
};
}
为具体字段创建独立校验器实例
每个输入框对应一个闭包实例,互不干扰。例如邮箱和密码字段各自拥有自己的规则和错误状态:
const emailValidator = createValidator();
emailValidator.addRule(v => v && /\S+@\S+\.\S+/.test(v), '请输入有效的邮箱');
emailValidator.addRule(v => v.length <= 100, '邮箱长度不能超过 100 字符');
const pwdValidator = createValidator();
pwdValidator.addRule(v => v && v.length >= 8, '密码至少 8 位');
pwdValidator.addRule(v => /[A-Z]/.test(v), '密码需包含大写字母');
// 使用示例
emailValidator.setValue('user@');
emailValidator.validate(); // false
console.log(emailValidator.getErrors()); // ['请输入有效的邮箱']
结合 DOM 实现实时校验反馈
将校验器绑定到 input 元素,监听事件并更新 UI:
立即学习“Java免费学习笔记(深入)”;
- 监听
input更新值,blur触发完整校验 - 根据
isInvalid()切换输入框边框颜色或显示错误提示元素 - 错误信息用
getErrors()获取,避免未失焦时过早提示
const emailInput = document.getElementById('email');
const emailError = document.getElementById('email-error');
const emailVal = createValidator();
emailVal.addRule(v => v && /\S+@\S+\.\S+/.test(v), '邮箱格式不正确');
emailVal.addRule(v => v.length <= 100, '邮箱太长了');
emailInput.addEventListener('input', () => {
emailVal.setValue(emailInput.value);
});
emailInput.addEventListener('blur', () => {
emailVal.validate();
emailError.textContent = emailVal.isInvalid()
? emailVal.getErrors().join(';')
: '';
emailInput.classList.toggle('error', emailVal.isInvalid());
});
扩展:支持异步规则(如用户名唯一性检查)
闭包内可维护 Promise 状态,提供 validateAsync 方法,返回 Promise,并区分同步/异步错误:
- 异步规则单独存入
asyncRules数组 -
validateAsync()先跑同步校验,再并发执行异步规则 - 错误统一收集,支持 .then/.catch 链式处理
// 在 createValidator 内部添加:
let asyncRules = [];
// ……
validateAsync() {
const syncOk = this.validate();
if (!syncOk) return Promise.resolve(false);
const asyncChecks = asyncRules.map(({ test, message }) =>
test(value).then(ok => ok ? undefined : message)
);
return Promise.all(asyncChecks).then(results => {
errors = results.filter(Boolean);
return errors.length === 0;
});
}


















