在js逻辑运算中,0、””、null、false、undefined、NaN都会判为false,其他都为true.
|| 先计算第一个运算数,如果可以被转换成true,则返回左边这个表达式的值,否则计算第二个运算数。即使||运算符的运算数不是布尔值,任然可以将它看作布尔OR运算,因为无论它返回的值是什么类型,都可以被转换为布尔值。
&& 它先计算第一个表达式,若为假,就不会去处理第二个表达;否则继续处理后继表达式。从左到右选取表达式的第一个为非true的表达式的值,如果一直未找到则返回最后一个表达式的值。
例一:
if( a == 3 ){ alert("OK"); }
简写成:
a==3 && alert(“OK”);
例二:
var a = 3, b; if(a == 3){ b = 6; } else if(a == 2){ b = 4; } else{ b = 1; }
简写成:
b = a==3 && 6 || a==2 && 4 || 1;
例三(不适用场合):
if( a == 3 ){ alert("Yes"); }else{ alert("No"); }
按之前的逻辑应该是:
a==3 && alert(“Yes”) || alert(“No”);
测试结果为 a == 3 为 true时,alert(“Yes”) 与 alert(“No”) 都会执行。
原因: alert(“Yes”)执行后,因为没有返回值,结果为 undefined ,也就会继续计算右边的表达式。
解决方法:
1.对于没有返回值的函数 // -> a==3 && alert(“Yes”)==undefined || alert(“No”);
2.对于返回值为空,或者转换为布尔值为 false 的函数 // -> a==3 && !alert(“Yes”) || alert(“No”);
注:短路写法用在特定地方,精炼代码,增强逻辑感,在代码中大批量使用的话,还是不太理想,慎重选择
看经典栗子: 提取一个数组的数据,允许提取的数组元素下标为 1、3、6、7、8
var test = (function(arr){ return function(i){ if( arr[i] != undefined ){ if(i==1){ return arr[i]; } else if(i==3){ return arr[i]; } else if(i==6){ return arr[i]; } else if(i==7){ return arr[i]; } else if(i==8){ return arr[i]; } else{ return "没有权限"; } }else{ return "错误的参数"; } } })([1,2,3,4,5,6,7,8,9,10]); test(3) // -> 4 test(6) // -> 7 test(7) // -> 8 test(2) // -> "没有权限" test(20) // -> "错误的参数"
精简代码:
var test = (function(arr){ return function(i){ return arr[i] != undefined && ( i==1&&arr[i] || i==3&&arr[i] || i==6&&arr[i] || i==7&&arr[i] || i==8&&arr[i] || "没有权限" ) || "错误的参数"; } })([1,2,3,4,5,6,7,8,9,10]); test(3) // -> 4 test(6) // -> 7 test(7) // -> 8 test(2) // -> "没有权限" test(20) // -> "错误的参数"
再简单点:
var test = (function(arr){ return function(i){ return i in arr && ( (i==1||i==3||i==6||i==7||i==8) && arr[i] || "没有权限" ) || "错误的参数"; } })([1,2,3,4,5,6,7,8,9,10]); test(3) // -> 4 test(6) // -> 7 test(7) // -> 8 test(2) // -> "没有权限" test(20) // -> "错误的参数"
强大的表达式,再看另一种例子
var a = 0; var b; function test(i){ if(i==3){ b=10; } else if(i==4){ b=23; } else if(i==6){ b=44; } else{ b=null; } }
可简写成
var a = 0; var b; function test(i){ b = {"3":10, "4":23, "6":44}[i] || null; }