使用JavaScript策略模式优化前端表单校验
本文介绍如何使用JavaScript策略模式重构前端表单校验逻辑。通过将校验规则封装为策略对象,利用Validator类统一管理规则添加与执行,避免冗长的if-else判断。该方案符合开闭原则,显著提升代码复用性与可维护性,支持为单一表单项配置多条规则。
概述
在Web开发中,登录、注册等功能的表单提交是常见场景。在数据提交至后台之前,前端通常需要进行初步校验,例如检查字段是否为空、长度是否合规、密码格式是否符合规范等。这些前端校验能有效拦截不合规的表单提交,减轻服务器压力。
假设我们需要处理一个包含多项校验规则的表单,具体需求如下:
- 用户名字段不能为空。
- 密码字段的长度必须至少为6位。
- 手机号字段必须符合特定的格式规范。
未使用策略模式的表单校验
在未采用策略模式的传统开发中,开发者通常会直接在提交事件中编写校验逻辑,代码如下:
<body>
<form id="registerForm">
<label for="username">输入用户名:<input type="text" name="username"></label>
<label for="password">输入密码:<input type="password" name="password"></label>
<label for="phone">输入密码:<input type="text" name="phone"></label>
</form>
<script>
const form = document.querySelector('.registerForm');
form.onsubmit = function(){
if(form.username.value === ''){
alert('用户名不能为空')
return;
}
if(form.password.value.length < 6){
alert('密码长度不能小于6位')
return;
}
if(!/(^1[3|5|8][0-9]{9}$)/.test(form.phone.value)){
alert('手机号格式不正确')
return;
}
}
</script>
</body>
这种常见的编码方式存在明显的缺陷:
- onsubmit函数体过于庞大,内部包含大量的if-else分支,需要覆盖所有可能的校验规则。
- onsubmit函数缺乏弹性,若需新增或修改校验规则,必须直接修改该函数的内部实现,这违反了开放-闭合原则。
- 代码复用性较差,当开发新的表单功能时,往往需要复制大量重复的校验代码。
使用策略模式优化
首先,我们将具体的校验逻辑封装为一个策略对象:
const strategies = {
empty(value, errMsg){
if(value.length === 0){
return errMsg;
}
},
minLength(value, len, errMsg){
if(value.length < len){
return errMsg;
}
},
isMobile(value, errMsg){
if(!/(^1[3|5|8][0-9]{9}$)/.test(value)){
return errMsg;
}
}
}
此外,我们需要定义一个Validator类,用于向目标表单动态添加验证规则。其基本用法如下:
const validate = function(){
const validator = new Validator();
validator.add(Form.userName, 'empty', '用户名不能为空');
validator.add(Form.password, 'minLength:6', '密码长度不能少于6位');
validator.add(Form.phone, 'isMobile', '手机号码格式不正确');
const errMsg = validator.start();
return errMsg;
}
如代码所示,validator实例提供了add方法,该方法接收3个参数:第一个参数是需要验证的表单元素实例,第二个参数是验证方法名(冒号后跟随传入的参数),第三个参数是验证未通过时的错误提示信息。
start方法用于启动校验流程,如果校验未通过,该方法将返回未通过的提示信息列表,供后续业务逻辑处理。
Validator类的具体实现代码如下:
class Validator {
constructor(){
this.rules = [];
}
add(elem, rule, err){
const args_arr = rule.split(":");
this.rules.push(()=>{
const handler = args_arr.shift();
args_arr.unshift(elem.value);
args_arr.push(err);
return strategies[handler].apply(elem, args_arr)
})
}
start(){
let errmsg = []
for(let i = 0; i < this.rules.length; i++ ){
const err = this.rules[i]();
if(err){
errmsg.push(err)
}
}
return errmsg.join(",");
}
}
通过策略模式,我们采用配置化的方式完成了表单校验。这些封装好的规则可以在任何需要校验的表单中复用,极大地方便了规则的修改与代码复用。
为单一表单项增加多个验证规则
当前的代码实现存在一个局限:只能为某个表单项绑定单一的验证规则,无法实现一个表单元素对应多条验证规则的需求,因此代码仍有优化空间。
class Validator{
// ···
add(elem, rules){
rules.forEach(rule => {
const args_arr = rule.strategy.split(":");
this.rules.push(()=>{
const handler = args_arr.shift();
args_arr.unshift(elem.value);
args_arr.push(rule.errMsg);
return strategies[handler].apply(elem, args_arr)
})
});
}
// ···
}
const validate = function(){
const validator = new Validator();
validator.add(Form.username,[{
strategy: 'empty',
errMsg: '用户名不能为空'
}]);
validator.add(Form.password, [{
strategy: 'minLength:6',
errMsg: '密码长度不能少于6位'
}]);
validator.add(Form.phone, [{
strategy: 'isMobile',
errMsg: '手机号码格式不正确'
}, {
strategy: 'empty',
errMsg: '手机号不能为空'
}]);
const errMsg = validator.start();
return errMsg;
}
只需在调用add方法时传入一个对象数组,并在add函数内部添加相应的数组遍历处理逻辑即可实现。
策略模式的优点
主要优点包括:
- 避免使用多重条件选择语句,使代码结构更清晰。
- 实现开闭原则,使得函数的使用更加易于切换、易于理解且易于扩展。
- 提高代码复用程度,减少重复代码的编写。
总结
Peter Norvig曾指出,在函数作为一等对象的语言中,策略模式是隐形的,strategy本质上就是值为函数的变量。其核心是将封装好的策略函数作为参数传递给目标对象(target),由target调用执行。熟练掌握策略模式,不仅能深化对设计模式的理解,也能让我们更深刻地体会到函数式编程的优势。
以上就是如何使用JavaScript策略模式校验表单的详细内容,更多关于JavaScript资料请关注本站其它相关文章!
JS reduce实战:数组去重、扁平化与分组统计
2026-11-05 13:05:36
JS代码怎么在线压缩?新手操作指南与工具推荐
2026-11-04 18:07:25
fflate 与 pako.js 性能对比:JS 解压库怎么选
2026-11-03 22:54:05
JS DOM查询性能优化:缓存引用与减少重排重绘
2026-11-03 22:48:27
在线运行JavaScript代码时的沙箱限制与跨域问题
2026-11-03 22:29:33
相关标签:
