¶My Solution
My solution to task30 is available on jsfiddle:
- 😕 这个实现中不太优雅的地方:
- 分别为每个 input都定义了一个check 函数,虽然有利用checkValue复用一部分代码。。
- 为了改变 this使用了很多很多的.call()方法。。
- blur的事件委托(历史遗留问题)。。
 
- 分别为每个 
- 😕 这个实现中不太可靠的地方:
- 各项的验证规则(正则)
- 寄生组合式继承
- Error构造函数传递- message参数无效。。(See Line 91)
 
 
¶Compared with others’
¶任务得分第一的团队的 solution
- 🎀 巧妙地各种运用数组及其方法
- 
hintText数组1 
 2
 3
 4
 5
 6var hintText = [{ hint: "必填,长度为4~16位字符", right: "名称格式正确", wrong: "名称格式有误", isPassed: false }, 
 { hint: "必填,长度为4~16位字符,包含字母和数字", right: "密码可用", wrong: "密码不可用", isPassed: false },
 { hint: "必填,必须与密码相同", right: "密码输入一致", wrong: "密码输入不一致", isPassed: false },
 { hint: "填写正确的邮箱格式", right: "邮箱格式正确", wrong: "邮箱格式错误", isPassed: false },
 { hint: "必填,长度为4~16位字符", right: "手机格式正确", wrong: "手机格式错误", isPassed: false }
 ];
- 
利用数组的 .forEach()和.every()方法来验证所有输入1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29// 我的写法不优雅之处: 
 // 1. 为每个 input 分别定义了检查函数,需要传入相关 dom 元素。
 // 2. 提交验证时,if 判断条件由一堆很长的 && 组成。
 addEventHandler(verifyBtn, "click", function() {
 var rawVal = nameDOM.value;
 if (checkName.call(nameDOM) && checkPwd.call(pwdDOM) && checkRepeatPwd.call(repeatPwdDOM) && checkEmail.call(emailDOM) && checkMobile.call(mobileDOM)) {
 alert("提交(验证)成功!");
 } else {
 alert("请按提示输入正确的信息后,再提交。");
 }
 });
 // 该团队的写法:
 // 1. 由于在 html 中定义了包含数字的 id 作为钩子,
 // 其检查函数只需传入对应的序号做参数即可找到相关 dom ,而不需要像我那样传入 dom 作为参数。
 // 2. hintText 在存储提示信息的同时存储了检查状态。
 // 在提交时,先是 .forEach() 地 checkValue 一遍,再利用 .every() 得到验证结果的 flag 值。
 addEventHandler(document.getElementById("submit"), "click", function(e) {
 e.preventDefault();
 [1, 2, 3, 4, 5].forEach(function(el) {
 checkValue(el);
 });
 var flag = hintText.every(function(singleHint) {
 return singleHint.isPassed;
 });
 if (flag)
 alert("提交成功");
 else
 alert("提交失败");
 });
- 
事件循环绑定 可以利用数组的 .forEach()方法 避开闭包(虽然这里真正避开闭包的原因是使用了节点的 id 中包含的数字,而没有使用 for 循环中的计数器 i ,但是使用数组的循环方法取代通常的 for 循环,确实是避开闭包的一种可行方案。):1 
 2
 3
 4
 5
 6
 7
 8
 9var inputs = document.getElementsByTagName("input"); 
 [].forEach.call(inputs, function(elem) {
 var id = elem.getAttribute("id").slice(1);
 var hintID = "h" + elem.getAttribute("id").slice(1);
 addEventHandler(elem, "focus", function() {
 document.getElementById(hintID).style.display = "table-row";
 });
 addEventHandler(elem, "blur", function() { checkValue(id) });
 });
 
- 
¶任务得分第二的团队的 solution
- 事件循环绑定 利用事件回调函数的 e.target避开使用 for 循环的计数器 i (从而 避开闭包)
¶任务得分第三的团队的 solution
- ES6待读。。
¶各项验证
¶手机号
- 我的 /^\d{11}$/:11 位纯数字
- /^1\d{10}$/:第一位为 1 的 11 位纯数字
- /^1(3|4|5|7|8)\d{9}$/:考虑到前两位的 11 位纯数字