详解JavaScript 中 if / if...else...替换方式


Posted in Javascript onJuly 15, 2018

详解JavaScript 中 if / if...else...替换方式

说说烂大街的if/if...else...,程序中用得最多的流程判断语句。

对着曾经满屏的if/if...else...,心想能不能搞点事情,折腾点浪花浪里呀浪。

对顶着“这个需求很简单,怎么实现我不管,明天上线”的程序猿,答案必须YES。

"Write Less, Do More",学习进步的本质就是为了更有效率地偷懒。

废话说完,直接上方法汇总,让我们来一窥究竟:

switch改写if

// if 版本
var a = 1;
if(a > 1 && a < 5) {
 return 1
} else if(a > 5 && a < 10){
 return 5
}else{
 return 10
}

// switch 改版
switch(true){
 case (a > 1 && a < 5):
  return 1
 case (a > 5 && a < 10):
  return 5
 default:
  return 10
}

以上代码的switch...case...的用法实际使用不多,仅供参考。
 一般case为常量时switch...case...用得较多。

选择分支较多时,建议选用switch…case可提高程序的效率,但switch...case不足的地方在于只能处理字符或者数字类型的变量,if…else更加灵活,可用于判断表达式是否成立,比如if(a+b>c),if…else的应用范围更广。

三元运算符改写if

// if 版本
if (bool) {
 value = 1;
} else {
 value = 2;
}

// 三元运算符 版本
value = bool ? 1 : 2;
// 三元预算符 多个运算需要括号包裹 此处用了逗号表达式
return typeof foo === 'object'?(console.log(1),1):(console.log(2),2);

优点:代码简化,更加清爽,write less

缺点:复杂的三元运算符可读性较差,需友好注释

TIPS: 三元运算符后面不能带return
// 错误用法,运算符号后不能带return
bool ? return 1 : return 2;

逻辑判断 and(&&)和or(||) 改写if

原理:利用逻辑判断的短路运算来实现

短路:&& 中第一个表达式为假就不会去处理第二个表达式,|| 则相反

// if为真
if (bool) {
 value = getYes();
}
// &&改版
bool && (value = getYes());

// if为假
if (!bool) {
 value = getNo();
}
bool || (value = getNo());

优点:代码简化,更加清爽,write less

缺点:适用于简单判断逻辑,复杂的判断运算可读性较差,需友好注释

TIPS:适用于没有else的场景, 逻辑运算符后面不能带return

// 错误用法,运算符号后不能带return
boll || return true;

--------------------------------------------------------------------------------

知识点插播 —— (1)

1.三元运算符和逻辑运算符都有一层return作用,但不可作用于函数return语句,所以像以下这种用法都是错误的;

// 错误用法
function getResult(value) {
 value ? 'yes' : 'no';
}
var result = getResult(true); // 并不会有值返回
1.js逻辑运算中,0/""/null/false/undefined/NaN都会判为false,其它都为true;
2.很多开源代码中可见if(!!attr),为什么不直接写if(attr), 其实这是一种更严谨的写法,!!attr会强制转化为boolean类型。typeof !!attr == true 比 typeof attr == true 更加严谨。
--------------------------------------------------------------------------------
对象属性
// if版本
if (a == 1) {
 return 'one';
} else if (a == 2) {
 return 'two';
} else if (a == 3) {
 return 'three';
} else {
 return '';
}
// 对象属性 改版
var ret = {
 1: 'one',
 2: 'two',
 3: 'three'
};
return ret[a] ? ret[a] : '';
TIPS:

1.判断值需为确定值,如== ,其它如>=/<=/>/<不适用
2.条件作为对象属性,需要注意对象属性的读取方式

--------------------------------------------------------------------------------

知识点插播 —— (2)

JS的命名规则(变量的命名规则)

•标识符只能由字母、数字、下划线和‘$'组成
•数字不可以作为标识符的首字符

对象属性的命名规则

•通过[]操作符为对象添加属性时,属性名可以是任何字符串(包括只包含空格的字符串和空字符串);
•通过.操作符为对象添加属性时,属性名必须是合法的标识符名称;
•如果属性名包含非法的标识符字符,则只能采用obj[“propertyName”]的形式;
•如果属性名是合法的标识符,读取时可采用obj.propertyName或obj[“propertyName”]的形式;

--------------------------------------------------------------------------------

策略模式

策略模式:定义一系列的算法,把它们一个个封装起来,目的就是将算法的使用与算法的实现分离开来

以下为常见的表单验证,用策略模式来构建,替换if...else的方式

// html
<form id = "registerForm" method="post" action="http://xxxx.com/api/register">
 用户名:<input type="text" name="userName">
 密码:<input type="text" name="password">
 手机号码:<input type="text" name="phoneNumber">
 <button type="submit">提交</button>
</form>
// js
// 策略对象
var strategies = {
 isNoEmpty: function (value, errorMsg) {
  if (value === '') {
   return errorMsg;
  }
 },
 isNoSpace: function (value, errorMsg) {
  if (value.trim() === '') {
   return errorMsg;
  }
 },
 minLength: function (value, length, errorMsg) {
  if (value.trim().length < length) {
   return errorMsg;
  }
 },
 maxLength: function (value, length, errorMsg) {
  if (value.length > length) {
   return errorMsg;
  }
 },
 isMobile: function (value, errorMsg) {
  if (!/^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|17[7]|18[0|1|2|3|5|6|7|8|9])\d{8}$/.test(value)) {
   return errorMsg;
  }    
 }
}
// 验证类
var Validator = function() {
 this.cache = [];
}
Validator.prototype.add = function(dom, 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(dom.value);
   strategyAry.push(errorMsg);
   return strategies[strategy].apply(dom, strategyAry);
   })
  })(rule)
 }
};
Validator.prototype.start = function() {
 for(var i = 0, validatorFunc; validatorFunc = this.cache[i++];) {
  var errorMsg = validatorFunc();
  if (errorMsg) {
   return errorMsg;
  }
 }
};
// 调用代码
var registerForm = document.getElementById('registerForm');
var validataFunc = function() {
 var validator = new Validator();
 validator.add(registerForm.userName, [{
  strategy: 'isNoEmpty',
  errorMsg: '用户名不可为空'
 }, {
  strategy: 'isNoSpace',
  errorMsg: '不允许以空白字符命名'
 }, {
  strategy: 'minLength:2',
  errorMsg: '用户名长度不能小于2位'
 }]);
 validator.add(registerForm.password, [ {
  strategy: 'minLength:6',
  errorMsg: '密码长度不能小于6位'
 }]);
 validator.add(registerForm.phoneNumber, [{
  strategy: 'isMobile',
  errorMsg: '请输入正确的手机号码格式'
 }]);
 var errorMsg = validator.start();
 return errorMsg;
}
registerForm.onsubmit = function() {
 var errorMsg = validataFunc();
 if (errorMsg) {
  alert(errorMsg);
  return false;
 }
}

•第一个部分是一组策略类,策略类封装了具体的算法,并负责具体的计算过程;
•第二个部分是环境类Context,该Context接收客户端的请求,随后把请求委托给某一个策略类;

优点:

1.有效避免多重条件选择语句
2.提供了对外开放 - 封装原则的完美支持,将方法封装在独立的strategy中,使得它们易于切换、易于理解、易于扩展。
3.复用性

缺点:

1.增加了策略类/对象的使用
2.使用策略模式,必须先了解所有的strategy,违反了最少知识原则

总结

以上所述是小编给大家介绍的JavaScript 中 if / if...else...替换方式 ,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

Javascript 相关文章推荐
利用Dojo和JSON建立无限级AJAX动态加载的功能模块树
Mar 24 Javascript
使用Jquery搭建最佳用户体验的登录页面之记住密码自动登录功能(含后台代码)
Jul 10 Javascript
简单漂亮的js弹窗可自由拖拽且兼容大部分浏览器
Oct 22 Javascript
JS实现可缩放、拖动、关闭和最小化的浮动窗口完整实例
Mar 04 Javascript
jquery插件orbit.js实现图片折叠轮换特效
Apr 14 Javascript
JavaScript实现简单的数字倒计时
May 15 Javascript
vue.js表格组件开发的实例详解
Oct 12 Javascript
bootstrap多层模态框滚动条消失的问题
Jul 21 Javascript
详细介绍RxJS在Angular中的应用
Sep 23 Javascript
js装饰设计模式学习心得
Feb 17 Javascript
微信小程序实现的自定义分享功能示例
Feb 12 Javascript
详解Nuxt.js 实战集锦
Nov 19 Javascript
简述JS控制台的使用
Jul 15 #Javascript
简述JS浏览器的三种弹窗
Jul 15 #Javascript
Vue路由钩子之afterEach beforeEach的区别详解
Jul 15 #Javascript
js+SVG实现动态时钟效果
Jul 14 #Javascript
vue实现通讯录功能
Jul 14 #Javascript
微信小程序自定义组件实现tabs选项卡功能
Jul 14 #Javascript
微信小程序scroll-view仿拼多多横向滑动滚动条
Apr 21 #Javascript
You might like
Yii实现简单分页的方法
2016/04/29 PHP
php 使用fopen函数创建、打开文件详解及实例代码
2016/09/24 PHP
PHP实现登陆表单提交CSRF及验证码
2017/01/24 PHP
ecshop添加菜单及权限分配问题
2017/11/21 PHP
让你的博文自动带上缩址的实现代码,方便发到微博客上
2010/12/28 Javascript
jQuery判断元素是否是隐藏的代码
2011/04/24 Javascript
一个简单的js树形菜单
2011/12/09 Javascript
Jquery阻止事件冒泡 event.stopPropagation
2011/12/11 Javascript
分享一个自定义的console类 让你不再纠结JS中的调试代码的兼容
2012/04/20 Javascript
jQuery实现的进度条效果
2015/07/15 Javascript
简单的JS时钟实例讲解
2016/01/13 Javascript
AngularJS入门教程之过滤器详解
2016/08/19 Javascript
js判断所有表单项不为空则提交表单的实现方法
2016/09/09 Javascript
js实现table添加行tr、删除行tr、清空行tr的简单实例
2016/10/15 Javascript
微信小程序 scroll-view实现上拉加载与下拉刷新的实例
2017/01/21 Javascript
解决jQuery ajax动态新增节点无法触发点击事件的问题
2017/05/24 jQuery
详解使用vue-cli脚手架初始化Vue项目下的项目结构
2018/03/08 Javascript
Vue+Typescript中在Vue上挂载axios使用时报错问题
2019/08/07 Javascript
js 计算月/周的第一天和最后一天代码
2020/02/01 Javascript
详解webpack的clean-webpack-plugin插件报错
2020/10/16 Javascript
[36:17]DOTA2上海特级锦标赛 - VGL音乐会全集
2016/03/06 DOTA
python实现ipsec开权限实例
2014/11/11 Python
Python比较文件夹比另一同名文件夹多出的文件并复制出来的方法
2015/03/05 Python
简单介绍Python中的JSON使用
2015/04/28 Python
python如何获取服务器硬件信息
2017/05/11 Python
Python3离线安装Requests模块问题
2019/10/13 Python
Python中base64与xml取值结合问题
2019/12/22 Python
Python日志syslog使用原理详解
2020/02/18 Python
python利用datetime模块计算程序运行时间问题
2020/02/20 Python
Python新手如何理解循环加载模块
2020/05/29 Python
python如何编写win程序
2020/06/08 Python
美国奢侈品购物平台:Orchard Mile
2018/05/02 全球购物
几道PHP的面试题
2012/05/19 面试题
电视购物广告词
2014/03/19 职场文书
劳动纠纷调解协议书格式
2014/11/30 职场文书
满月酒邀请函
2015/01/30 职场文书