『逻辑与』是个好东西
一直很想实现 WebForms2 的语义化表单验证,最近才开始动手,执行力真差啊。
一个表单元素可以同时存在多种校验方案,比如:
- required.
- data type: number, date, url, email...
- minlength, maxlength, min, max.
- pattern
- 用户自定义验证函数。
- 异步访问服务器进行业务校验。
通常可以通过逻辑判断进行处理:
1function verifyFormInput(input){
2 if(!verifyRequired()){return false;}
3 if(!verifyMinLength()){return false;}
4 if(!verifyMaxLength()){return false;}
5 if(!verifyInputType()){return false;}
6 if(!verifyMin()){return false;}
7 if(!verifyMax()){return false;}
8 if(!verifyPattern()){return false;}
9 if(!verifyUserRules()){return false;}
10 if(!verifySync()){return false;}
11 return true;
12}
13function verifyForm(form){
14 var flags = [];
15 for(var i=0,l=form.elements.length; i<l; i++){
16 // 一次只能校验一个表单元素异常。
17 //if(!verifyFormInput(form.elements[i])){return false;}
18
19 // 可以同时校验所有元素异常。但是需要辅助循环进行检查。
20 flags[i] = verifyFormInput(form.elements[i]);
21 }
22 // 辅助循环检查。
23 for(var i=0,l=flags.length; i<l; i++){
24 if(!flags[i]){return false;}
25 }
26 return true;
27}
实际代码中,各个 verifyXXX 函数可能内联在 verifyFormInput 函数中,
代码显得多而有点乱,甚至有点冗余。
想起模拟电路课程上学到的『与门』,只有所有电路都是通路时,整个电路才是通路。
而表单验证也是这样:
- 某个表单元素的所有验证逻辑都通过验证时,这个表单元素才算通过验证。
- 整个表单的所有表单元素都通过验证时,才算这个表单通过验证。
同时基于『逻辑与』表达式的语言特性,一旦前面的条件可以判断逻辑失败,立即返回
失败,不再进行后面的条件判断。
LogicalANDExpression:
Semantics
The production LogicalANDExpression : LogicalANDExpression &&
BitwiseORExpression is evaluated as follows:
- Evaluate LogicalANDExpression.
- Call GetValue(Result(1)).
- Call ToBoolean(Result(2)).
- If Result(3) is false, return Result(2).
- Evaluate BitwiseORExpression.
- Call GetValue(Result(5)).
- Return Result(6).
BitwiseORExpression:
Semantics
The production A : A@B, where @ is one of the bitwise operators in the
productions above, is evaluated as follows:
- Evaluate A.
- Call GetValue(Result(1)).
- Evaluate B.
- Call GetValue(Result(3)).
- Call ToInt32(Result(2)).
- Call ToInt32(Result(4)).
- Apply the bitwise operator @ to Result(5) and Result(6). The result is
a signed 32 bit integer.
- Return Result(7).
于是验证算法改良如下:
1function verifyFormInput(input){
2 var certified = true;
3 certified = certified && verifyRequired();
4 certified = certified && verifyMinLength();
5 certified = certified && verifyMaxLength();
6 certified = certified && verifyInputType();
7 certified = certified && verifyMin();
8 certified = certified && verifyMax();
9 certified = certified && verifyPattern();
10 certified = certified && verifyUserRules();
11 certified = certified && verifySync();
12 return certified;
13}
14function verifyForm(form){
15 var certified = true;
16 for(var i=0,flag,l=form.elements.length; i<l; i++){
17 // 一次只能校验一个表单元素异常。
18 //certified = certified && verifyFormInput(form.elements[i]);
19
20 // 可以同时校验所有元素异常。无需辅助循环进行检查。
21 flag = verifyFormInput(form.elements[i]);
22 certified = certified && flag;
23 }
24 return certified;
25}
延伸
以前也 Hack 的用过逻辑与表达式,比如:
但这个用法只是用到了条件判断的作用,类似于:
参考阅读
Tags: JavaScript
Published on 2012-05-01