2017.4.10 js 中的function 实现的方式实例系列:JS 策略模式-------- 表单验证

<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>

 

改栗子的关键问题是闭包,以及变量的引用,以及函数的执行环境问题。
因为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
          }

posted @ 2017-04-10 11:44  a fine day  阅读(186)  评论(0编辑  收藏  举报