<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<form id="registerForm">
<input type="text" id="username"/>
<input type="password" id="password"/>
<input type="text" id="telphoneNo"/>
<button id="submit">submit</button>
</form>
</body>
<script>
/**** 防止变量污染 ****/
(function(){
var Validator = function(){
this.cache = []; // 存储验证函数function{}
}
Validator.strategies = {
isNonEmpty : function(value,errorMsg){
if(!value) return errorMsg
},
minLength : function(value,length,errorMsg){
if(value.length < length) return errorMsg
},
isMobile : function(value,errorMsg){
if(!/^1[3|4|5|7|8][0-9]{9}$/.test(value)) return errorMsg
}
};
Validator.prototype.add = function(dom,rules){
if(!dom || !(Object.prototype.toString.call(rules) === "[object Array]")) return
var strategies = this.constructor.strategies;
var self = this
for(var i = 0;i < rules.length; i++){
(function(i){
var strategyArr = rules[i].strategy.split(":");
var errorMsg = rules[i].errorMsg;
self.cache.push(function(){
var strategy = strategyArr.shift();
strategyArr.unshift(dom.value);
strategyArr.push(errorMsg)
return strategies[strategy].apply(dom,strategyArr);
})
})(i);
}
}
Validator.prototype.start = function(){
for(var i = 0; i < this.cache.length ;i++){
var errorMsg = this.cache[i]();
if(errorMsg) return errorMsg
}
}
window.Validator = Validator;
})();
var validatorFun = function(){
var registerForm = document.querySelector("#registerForm");
var validator = new Validator();
validator.add(registerForm.username,[{
strategy : "isNonEmpty",
errorMsg : "用户名不能为空"
},{
strategy : "minLength:10",
errorMsg : "用户名长度不能小于10"
}]);
validator.add(registerForm.password,[{
strategy : "isNonEmpty",
errorMsg : "密码不能为空"
},{
strategy : "minLength:6",
errorMsg : "密码长度不能小于6"
}]);
validator.add(registerForm.telphoneNo,[{
strategy : "isNonEmpty",
errorMsg : "手机号不能为空"
},{
strategy : "isMobile",
errorMsg : "请输入正确的手机号"
}]);
var errorMsg = validator.start();
return errorMsg
}
document.querySelector("#submit").onclick = function(){
var errorMsg = validatorFun();
if(errorMsg) alert(errorMsg)
}
</script>
</html>
改栗子的关键问题是闭包,以及变量的引用,以及函数的执行环境问题。
1 因为push的是函数,函数中有对变量strategyArr的引用,所以形成了闭包。
2 变量的引用
如果变量的值是引用类型的地址。传递过程中的该变量就是引用传递。 所以本栗子中的strategyArr,是有i的数组
var strategyArr = rules[i].strategy.split(":");
var errorMsg = rules[i].errorMsg;
self.cache.push(function(){
var strategy = strategyArr.shift();
strategyArr.unshift(dom.value);
strategyArr.push(errorMsg)
return strategies[strategy].apply(dom,strategyArr);
})
3 首先说下函数的执行环境问题。
对于类似 someElement.onclick = function(){
someFn(); //someFn(普通函数)的执行环境为window,someFn中的this指向window
}