轻松掌握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 相关文章推荐
js arguments.callee的应用代码
May 07 Javascript
javascript向flash swf文件传递参数值注意细节
Dec 11 Javascript
jQuery实现类似淘宝购物车全选状态示例
Jun 26 Javascript
js报$ is not a function 的问题的解决方法
Jan 20 Javascript
javascript实现简单的贪吃蛇游戏
Mar 31 Javascript
详解javascript事件冒泡
Jan 09 Javascript
vue2.0 axios前后端数据处理实例代码
Jun 30 Javascript
vue-cli 引入、配置axios的方法
May 08 Javascript
JavaScript new对象的四个过程实例浅析
Jul 31 Javascript
Vue请求java服务端并返回数据代码实例
Nov 28 Javascript
如何在vue中使用jointjs过程解析
May 29 Javascript
用JS创建一个录屏功能
Nov 11 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下escape解码函数的实现方法
2010/08/08 PHP
php.ini中date.timezone设置分析
2011/07/29 PHP
PHP读取数据库并按照中文名称进行排序实现代码
2013/01/29 PHP
php基于socket实现SMTP发送邮件的方法
2015/03/05 PHP
如何使用GDB调试PHP程序
2015/12/08 PHP
一段非常简单的让图片自动切换js代码
2006/11/10 Javascript
jquery 弹出登录窗口实现代码
2009/12/24 Javascript
统计jQuery中各字符串出现次数的工具
2012/05/03 Javascript
jQuery插件Slider Revolution实现响应动画滑动图片切换效果
2015/06/05 Javascript
jQuery实现带滑动条的菜单效果代码
2015/08/26 Javascript
RequireJS 依赖关系的实例(推荐)
2017/01/21 Javascript
Vue添加请求拦截器及vue-resource 拦截器使用
2017/11/23 Javascript
JavaScript实现省市联动过程中bug的解决方法
2017/12/04 Javascript
基于vue2.0的活动倒计时组件countdown(附源码下载)
2018/10/09 Javascript
JS监听事件的叠加和移除功能
2018/11/19 Javascript
Vue+Django项目部署详解
2019/05/30 Javascript
教你完全理解ReentrantLock重入锁
2019/06/03 Javascript
vue实现权限控制路由(vue-router 动态添加路由)
2019/11/04 Javascript
[01:29]2017 DOTA2国际邀请赛官方英雄手办展示
2017/03/18 DOTA
[28:48]《真视界》- 2017年国际邀请赛
2017/09/27 DOTA
在Django的模板中使用认证数据的方法
2015/07/23 Python
解决PyCharm import torch包失败的问题
2018/10/13 Python
python创建子类的方法分析
2019/11/28 Python
python 操作hive pyhs2方式
2019/12/21 Python
python已协程方式处理任务实现过程
2019/12/27 Python
python输出pdf文档的实例
2020/02/13 Python
Python命令行参数定义及需要注意的地方
2020/11/30 Python
New Balance加拿大官方网站:运动鞋和健身服装
2018/11/19 全球购物
党员一句话承诺大全
2014/03/28 职场文书
学校交通安全责任书
2014/08/25 职场文书
党性锻炼的心得体会
2014/09/03 职场文书
2015年八一建军节演讲稿
2015/03/19 职场文书
费用申请报告范文
2015/05/15 职场文书
导游词之上海豫园
2019/10/24 职场文书
浅谈sql_@SelectProvider及使用注意说明
2021/08/04 Java/Android
Python机器学习应用之基于线性判别模型的分类篇详解
2022/01/18 Python