轻松掌握JavaScript策略模式


Posted in Javascript onAugust 25, 2016

定义:定义一系列的算法,把它们一个个封装成函数,也可把它们作为属性统一封装进一个对象,然后再定义一个方法,该方法可根据参数自动选择执行对应的算法。 

一般用于在实现一个功能时,有很多个方案可选择的情况。 

例子1:根据员工薪水salary、绩效等级S、A、B、C,来计算年终奖

//封装了所有算法的策略对象
var strategies = {
  'S': function(salary){
    return salary*4;
  },
  'A': function(salary){
    return salary*3;
  },
  'B': function(salary){
    return salary*2;
  },
  'C': function(salary){
    return salary*1;
  }
} //定义自动选择算法的方法
var calculateBonus = function(level,salary){
  return strategies[level](salary);
}
//使用
calculateBonus('S',9000); //36000
calculateBonus('B',5000); //10000

例子2:表单验证

//定义验证算法的策略对象
var strategies = function(){
  isEmpty:function(value,errorMsg){
    if(value = ''){
      return errorMsg;
    }
  }
  outRangle:function(value,min,max,errorMsg){
    if(value.length > max || value.length < min){
      return errorMsg;
    }
  }
  isSame:function(oldValue,newValue,errorMsg){
    if(newValue !== oldValue){
      return errorMsg;
    }
  }
  isMobile:function(value,errorMsg){
    if(!/(^1[3|5|8][0-9]{9}$)/.test(value)){
      return errorMsg;
    }
  }
  ......
}

也可不定义以下的Validator类,直接在触发失去焦点事件时调用strategies对象的属性方法来验证当前input项

//定义Validator
var Validator = function(){
  this.cache = [];
}
Validator.prototype.add = function(elem,rules){
  var self = this;
  for(var i = 0, rule; rule = rules[i++]){
    (function(rule){
      var strategyAry = rule.strategy.split(':');
      var errorMsg = rule.errorMsg;
      self.cache.push(function(){
        var strategy = strategyAry.shift();
        strategyAry.unshift(elem.value);
        strategyAry.push(errorMsg);
        return strategies[strategy].apply(elem,strategyAry);
      })
    })(rule)
  }
}
Validator.prototype.start = function(){
  for(var i = 0, func; func = this.cache[i++]){
    var errorMsg = func();
    if(errorMsg){
      return errorMsg;
    }
  }
}

使用:

var validator = new Validator();
validator.add(elem.userName,[
  {strategy:'isEmpty', errorMsg:'用户名不能为空'},
  {strategy:'outRangle:6:12', errorMsg:'用户名长度为6-12位'}
]);
......
var errorMsg = validator.start();
......

附:参数配置对象 
假如有一个函数foo(a,b,c,d,e,f...),它的参数很多,这样的函数不好使用,参数不好记!比较好的方法是使用一个对象来包含这些参数,然后再把该对象传递给函数,函数再对这个对象的属性做处理

var prop = {
  a:55,
  b:'ss',
  c:function(){...}
  d:{x:1,y:2}
  ...
}
foo(prop);

这样一来,使用函数时就不必去记参数顺序了,只需记住参数对象的几个属性名字就行,不易出错 
参考文献: 《JavaScript模式》 《JavaScript设计模式与开发实践》

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Javascript公共脚本库系列(一): 弹出层脚本
Feb 24 Javascript
js onclick事件传参讲解
Nov 06 Javascript
jQuery实现响应鼠标滚动的动感菜单效果
Sep 21 Javascript
跟我学习JScript的Bug与内存管理
Nov 18 Javascript
jQuery操作Table技巧大汇总
Jan 23 Javascript
DOM 事件的深入浅出(一)
Dec 05 Javascript
利用prop-types第三方库对组件的props中的变量进行类型检测
May 02 Javascript
vue.js中$set与数组更新方法
Mar 08 Javascript
快速搭建Node.js(Express)用户注册、登录以及授权的方法
May 09 Javascript
JavaScript canvas绘制圆弧与圆形
Feb 18 Javascript
vue项目中微信登录的实现操作
Sep 08 Javascript
在vue项目中 实现定义全局变量 全局函数操作
Oct 26 Javascript
Javascript 6里的4个新语法
Aug 25 #Javascript
Javascript实现代码折叠功能
Aug 25 #Javascript
深入浅出ES6之let和const命令
Aug 25 #Javascript
PhotoSwipe异步动态加载图片方法
Aug 25 #Javascript
相册展示PhotoSwipe.js插件实现
Aug 25 #Javascript
移动端点击图片放大特效PhotoSwipe.js插件实现
Aug 25 #Javascript
手机端图片缩放旋转全屏查看PhotoSwipe.js插件实现
Aug 25 #Javascript
You might like
PHP浮点数精度问题汇总
2015/05/13 PHP
PHP自带方法验证邮箱是否存在
2016/02/01 PHP
javascript高亮效果的二种实现方法
2008/09/14 Javascript
如何确保JavaScript的执行顺序 之jQuery.html深度分析
2011/03/03 Javascript
js时间戳格式化成日期格式的多种方法
2013/11/11 Javascript
javascript 数字格式化输出的实现代码
2013/12/10 Javascript
javascript动画系列之模拟滚动条
2016/12/13 Javascript
jquery插件ContextMenu设置右键菜单
2017/03/13 Javascript
初学者AngularJS的环境搭建过程
2017/10/27 Javascript
浅谈es6 javascript的map数据结构
2017/12/14 Javascript
JavaScript实现的反序列化json字符串操作示例
2018/07/18 Javascript
Vue表单之v-model绑定下拉列表功能
2019/05/14 Javascript
javascript实现简易数码时钟
2020/03/30 Javascript
浅谈JavaScript中this的指向更改
2020/07/28 Javascript
Antd下拉选择,自动匹配功能的实现
2020/10/24 Javascript
[02:15]你好,这就是DOTA!
2015/08/05 DOTA
[01:06:42]VP vs NewBee Supermajor 胜者组 BO3 第二场 6.5
2018/06/06 DOTA
Python正则表达式匹配HTML页面编码
2015/04/08 Python
python实现Floyd算法
2018/01/03 Python
python opencv实现切变换 不裁减图片
2018/07/26 Python
python将控制台输出保存至文件的方法
2019/01/07 Python
Python3.4学习笔记之类型判断,异常处理,终止程序操作小结
2019/03/01 Python
selenium 安装与chromedriver安装的方法步骤
2019/06/12 Python
python web框架Flask实现图形验证码及验证码的动态刷新实例
2019/10/14 Python
CSS3 rgb and rgba(透明色)的使用详解
2020/09/25 HTML / CSS
美国祛痘、抗衰老药妆品牌:Murad
2016/08/27 全球购物
Joules美国官网:出色的英国风格
2017/10/30 全球购物
Notino瑞典:购买香水和美容产品
2019/07/26 全球购物
工商治理实习生的自我评价
2014/01/15 职场文书
党校培训自我鉴定
2014/02/01 职场文书
运动会闭幕式解说词
2014/02/21 职场文书
协议书怎么写
2014/04/21 职场文书
服务理念口号
2014/06/11 职场文书
英文投诉信格式
2015/07/03 职场文书
Jupyter notebook 不自动弹出网页的解决方案
2021/05/21 Python
Python访问Redis的详细操作
2021/06/26 Python