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 相关文章推荐
javascript 进阶篇1 正则表达式,cookie管理,userData
Mar 14 Javascript
使用apply方法实现javascript中的对象继承
Dec 16 Javascript
node.js中的fs.createReadStream方法使用说明
Dec 17 Javascript
JS如何实现文本框随文本的长度而增长
Jul 30 Javascript
js实现千分符和保留几位小数的简单实例
Aug 01 Javascript
十个免费的web前端开发工具详细整理
Sep 18 Javascript
基于IView中on-change属性的使用详解
Mar 15 Javascript
Vue中的无限加载vue-infinite-loading的方法
Apr 08 Javascript
angularJs中跳转到指定的锚点实例($anchorScroll)
Aug 31 Javascript
了解JavaScript中let语句
May 30 Javascript
如何在wxml中直接写js代码(wxs)
Nov 14 Javascript
关于Vue Router的10条高级技巧总结
May 06 Vue.js
测试你的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
Terran历史背景
2020/03/14 星际争霸
十天学会php之第四天
2006/10/09 PHP
php相当简单的分页类
2008/10/02 PHP
php程序之die调试法 快速解决错误
2009/09/17 PHP
使用array mutisort 实现按某字段对数据排序
2013/06/18 PHP
php实现aes加密类分享
2014/02/16 PHP
php实现的用户查询类实例
2015/06/18 PHP
fsockopen pfsockopen函数被禁用,SMTP发送邮件不正常的解决方法
2015/09/20 PHP
php curl简单采集图片生成base64编码(并附curl函数参数说明)
2019/02/15 PHP
JS 实现点击a标签的时候让其背景更换
2013/10/15 Javascript
利用JS解决ie6不支持max-width,max-height问题的方法
2014/01/02 Javascript
JQuery中DOM事件合成用法实例分析
2015/06/13 Javascript
基于JavaScript实现移动端点击图片查看大图点击大图隐藏
2015/11/04 Javascript
JavaScript实现仿淘宝商品购买数量的增减效果
2016/01/22 Javascript
AngularJs 弹出模态框(model)
2016/04/07 Javascript
js两种拼接字符串的简单方法(必看)
2016/09/02 Javascript
Ajax与服务器(JSON)通信实例代码
2016/11/05 Javascript
node安装--linux下的快速安装教程
2017/03/21 Javascript
react-native ListView下拉刷新上拉加载实现代码
2017/08/03 Javascript
js前端导出Excel的方法
2017/11/01 Javascript
说说如何使用Vuex进行状态管理(小结)
2019/04/14 Javascript
Vue 修改网站图标的方法
2020/12/31 Vue.js
vue keep-alive的简单总结
2021/01/25 Vue.js
Python中MYSQLdb出现乱码的解决方法
2014/10/11 Python
Python简单删除目录下文件以及文件夹的方法
2015/05/27 Python
Python获取文件所在目录和文件名的方法
2017/01/12 Python
详解python持久化文件读写
2019/04/06 Python
Django中的静态文件管理过程解析
2019/08/01 Python
详解python中的index函数用法
2019/08/06 Python
Python实现密码薄文件读写操作
2019/12/16 Python
Python 限定函数参数的类型及默认值方式
2019/12/24 Python
tensorflow实现训练变量checkpoint的保存与读取
2020/02/10 Python
英国复古服装和球衣购买网站:3Retro Football
2018/07/09 全球购物
Ryderwear澳洲官网:澳大利亚高端健身训练装备品牌
2018/09/18 全球购物
学生个人总结范文
2015/02/15 职场文书
pytorch锁死在dataloader(训练时卡死)
2021/05/28 Python