js 与或运算符 || && 妙用


Posted in Javascript onDecember 09, 2009

首先出个题:
js 与或运算符 || && 妙用
如图:
假设对成长速度显示规定如下:
成长速度为5显示1个箭头;
成长速度为10显示2个箭头;
成长速度为12显示3个箭头;
成长速度为15显示4个箭头;
其他都显示都显示0各箭头。
用代码怎么实现?

差一点的if,else:
Js代码

var add_level = 0; 
if(add_step == 5){ 
add_level = 1; 
} 
else if(add_step == 10){ 
add_level = 2; 
} 
else if(add_step == 12){ 
add_level = 3; 
} 
else if(add_step == 15){ 
add_level = 4; 
} 
else { 
add_level = 0; 
}

稍好些的switch:
Js代码
var add_level = 0; 
switch(add_step){ 
case 5 : add_level = 1; 
break; 
case 10 : add_level = 2; 
break; 
case 12 : add_level = 3; 
break; 
case 15 : add_level = 4; 
break; 
default : add_level = 0; 
break;

}如果需求改成:
成长速度为>12显示4个箭头;
成长速度为>10显示3个箭头;
成长速度为>5显示2个箭头;
成长速度为>0显示1个箭头;
成长速度为<=0显示0个箭头。

那么用switch实现起来也很麻烦了。

那么你有没有想过用一行就代码实现呢?
ok,让我们来看看js强大的表现力吧:
Js代码

var add_level = (add_step==5 && 1) || (add_step==10 && 2) || (add_step==12 && 3) || (add_step==15 && 4) || 0;

更强大的,也更优的:

Js代码

var add_level={'5':1,'10':2,'12':3,'15':4}[add_step] || 0;

第二个需求:
Js代码
var add_level = (add_step>12 && 4) || (add_step>10 && 3) || (add_step>5 && 2) || (add_step>0 && 1) || 0;

首先我们来梳理一下一个概念,请你一定要记住:在js逻辑运算中,0、""、null、false、undefined、NaN都会判为false,其他都为true(好像没有遗漏了吧,请各位确认下)。这个一定要记住,不然应用||和&&就会出现问题。
这里顺便提下:经常有人问我,看到很多代码if(!!attr),为什么不直接写if(attr);
其实这是一种更严谨的写法:
请测试 typeof 5和typeof !!5的区别。!!的作用是把一个其他类型的变量转成的bool类型。
下面主要讨论下逻辑运算符&&和||。
几乎所有语言中||和&&都遵循“短路”原理,如&&中第一个表达式为假就不会去处理第二个表达式,而||正好相反。
js也遵循上述原则。但是比较有意思的是它们返回的值。
代码:var attr = true && 4 && “aaa”;
那么运行的结果attr就不是简单的true或这false,而是”aaa”
再来看看||:
代码:var attr = attr || “”;这个运算经常用来判断一个变量是否已定义,如果没有定义就给他一个初始值,这在给函数的参数定义一个默认值的时候比较有用。因为js不像php可以直接在型参数上定义func($attr=5)。再次提醒你记住上面的原则:如果实参需要是0、""、null、false、undefined、NaN的时候也会当false来处理。

if(a >=5){
alert("你好");
}
可以写成:
a >= 5 && alert("你好");
这样只需一行代码就搞定。但是需要注意的一点就是:js中||和&&的特性帮我们精简了代码的同时,也带来了代码可读性的降低。这就需要我们自己来权衡了。
一方面精简js代码,能实质性的减少网络流量,尤其是大量应用的js公用库。个人比较推荐的做法是:如果是相对复杂的应用,请适当地写一些注释。这个和正在表达式一样,能够精简代码,但是可读性会降低,对读代码的人要求会高些,最好的办法就是写注释。

我们可以不使用这些技巧,但是我们一定要能看懂,因为这些技巧已经广泛应用,尤其是像JQuery等js框里的代码,不理解这些你就很难看懂别人的代码。
像var Yahoo = Yahoo || {};这种是非常广泛应用的。
ok,最后让我们来看一段jQuery中的代码吧:

Js代码

var wrap = 
    // option or optgroup 
    !tags.indexOf("<opt") && 
    [ 1, "<select multiple='multiple'>", "</select>" ] ||     !tags.indexOf("<leg") && 
    [ 1, "<fieldset>", "</fieldset>" ] || 
    tags.match(/^<(thead|tbody|tfoot|colg|cap)/) && 
    [ 1, "<table>", "</table>" ] || 
    !tags.indexOf("<tr") && 
    [ 2, "<table><tbody>", "</tbody></table>" ] || 
    // <thead> matched above 
    (!tags.indexOf("<td") || !tags.indexOf("<th")) && 
    [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] || 
    !tags.indexOf("<col") && 
    [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] || 
    // IE can't serialize <link> and <script> tags normally 
    !jQuery.support.htmlSerialize && 
    [ 1, "div<div>", "</div>" ] || 
    [ 0, "", "" ]; 
    // Go to html and back, then peel off extra wrappers 
    div.innerHTML = wrap[1] + elem + wrap[2]; 
    // Move to the right depth 
    while ( wrap[0]-- ) 
        div = div.lastChild;

这段代码是作者用来处理 $(html) 时,有些标签必须要约束的,如<option>必须在<select></select>之内的。
可能你也发现了作者还有一个很巧的地方就是 !tags.indexOf("<opt") ,作者很巧很简单的就实现了startWith的功能了,没有一点多余的代码。jquery源代码中还有很多如此精妙的代码,大家可以去学习学习。

Javascript 相关文章推荐
js模拟弹出效果代码修正版
Aug 07 Javascript
一个JQuery操作Table的代码分享
Mar 30 Javascript
js二维数组定义和初始化的三种方法总结
Mar 03 Javascript
IE中图片的onload事件无效问题和解决方法
Jun 06 Javascript
jquery使用ul模拟select实现表单美化的方法
Aug 18 Javascript
jQuery fancybox在ie浏览器下无法显示关闭按钮的解决办法
Feb 19 Javascript
jquery自定义右键菜单、全选、不连续选择
Mar 01 Javascript
jQuery内容折叠效果插件用法实例分析(附demo源码)
Apr 28 Javascript
JS编写函数实现对身份证号码最后一位的验证功能
Dec 29 Javascript
vue-cli的工程模板与构建工具详解
Sep 27 Javascript
ionic3双击返回退出应用的方法
Sep 17 Javascript
vue cli3适配所有端方案的实现
Apr 13 Javascript
测试你的JS的掌握程度的代码
Dec 09 #Javascript
用javascript获取当页面上鼠标光标位置和触发事件的对象的代码
Dec 09 #Javascript
jMessageBox 基于jQuery的窗口插件
Dec 09 #Javascript
jQuery 开天辟地入门篇一
Dec 09 #Javascript
jquery tablesorter.js 支持中文表格排序改进
Dec 09 #Javascript
jquery 事件执行检测代码
Dec 09 #Javascript
为指定元素增加样式的js代码
Dec 09 #Javascript
You might like
php后台如何避免用户直接进入方法实例
2013/10/15 PHP
Laravel学习教程之路由模块
2017/08/18 PHP
PHP 数组黑名单/白名单实例代码详解
2019/06/04 PHP
firefox火狐浏览器与与ie兼容的2个问题总结
2010/07/20 Javascript
JS阻止冒泡事件以及默认事件发生的简单方法
2014/01/17 Javascript
Jquery倒计时源码分享
2014/05/16 Javascript
JavaScript中的对象序列化介绍
2014/12/30 Javascript
在线所见即所得HTML编辑器的实现原理浅析
2015/04/25 Javascript
Bootstrap中datetimepicker使用小结
2016/12/28 Javascript
JS正则RegExp.test()使用注意事项(不具有重复性)
2016/12/28 Javascript
jQuery实现手机上输入后隐藏键盘功能
2017/01/04 Javascript
ES6中参数的默认值语法介绍
2017/05/03 Javascript
Vue.js 2.5新特性介绍(推荐)
2017/10/24 Javascript
Parcel.js + Vue 2.x 极速零配置打包体验教程
2017/12/24 Javascript
vue2.0 移动端实现下拉刷新和上拉加载更多的示例
2018/04/23 Javascript
AngularJS模态框模板ngDialog的使用详解
2018/05/11 Javascript
浅谈webpack devtool里的7种SourceMap模式
2019/01/14 Javascript
js动态获取时间的方法分析
2019/08/02 Javascript
生成无限制的微信小程序码的示例代码
2019/09/20 Javascript
three.js中多线程的使用及性能测试详解
2021/01/07 Javascript
[00:57]辉夜杯战队访谈宣传片—VG
2015/12/25 DOTA
Python多线程、异步+多进程爬虫实现代码
2016/02/17 Python
python脚本设置超时机制系统时间的方法
2016/02/21 Python
利用 Monkey 命令操作屏幕快速滑动
2016/12/07 Python
Python Pandas 获取列匹配特定值的行的索引问题
2019/07/01 Python
基于Django实现日志记录报错信息
2019/12/17 Python
用Python进行websocket接口测试
2020/10/16 Python
River Island美国官网:英国高街时尚品牌
2018/09/04 全球购物
白俄罗斯女装和针织品网上商店:Presli.by
2019/10/13 全球购物
C#如何判断当前用户是否输入某个域
2015/12/07 面试题
外科实习自我鉴定
2013/10/06 职场文书
环境科学毕业生自荐信
2013/11/21 职场文书
面临毕业的毕业生自荐书范文
2014/02/05 职场文书
工商管理专业毕业生自我鉴定2014
2014/10/04 职场文书
实习生矿工检讨书
2014/10/13 职场文书
关于企业的执行力标语大全
2020/01/06 职场文书