数据类型
不像Java等语言中逻辑运算符与
、或
、非
只能作用于特定类型的数据,如在Java中只能作用于boolean/Boolean类型的操作数,JavaScript中的这些运算符可以作用于任意表达式
。
- 能转换成false的值(表达式):0, -0, null, false, NaN, undefined, ""(空字符串)
- 能转换成true的值(表达式):除了能转换成false的除外的都可以转换成true
当我们使用if(expr){...}
,while(expr){...}
等需要判断true/false的地方,表达式expr的值可以是任意类型的值,可以理解为实际使用的值是通过Boolean(expr)得到的true/false。
//这是一个常见的需求://我们的函数接受一个参数file,这个参数可以是一个对象,也可以是一个对象的数组,我们的函数要对一个或多个对象进行统一的处理//我们希望无论传入的是单个对象,还是一个数组,甚至是空的,都统一放进一个数组进行处理,我们可以这么写:function myFunc(file, otherArg){ var arr = []; if(file && !Array.isArray(arr)){ arr.push(file); }else{ arr.concat(file); } arr.forEach(function(item){/*do something with item*/});}//虽然Array.prototype.concat可以接受一个对象或者一个数组,但是我们怕传入的是undefined或null//因此我们可以做个过滤:function myFunc2(file, otherArg){ var arr = [].concat(file).filter(function(item){ return item; }); //do something with the arr}//发现没有,Boolean是一个函数,刚好可以作为Array.prototype.filter的参数,于是我们得到更简洁的写法:function myFunc3(file, otherArg){ var arr = [].concat(file).filter(Boolean); //do something with arr}
以上用法其实是笔者在github上很多高质量的项目中发现的,非常受用。善用语言的特性,可以让我们的代码更简洁,更优雅。
另外,有时候我们想得到一个对象/值对应的布尔值true/false,除了可以用Boolean函数,还可以用以下表达式!!expr
得到,参考下一节对逻辑非
运算符的介绍。 逻辑表达式的返回值
与例如Java的很多其他语言不同,JavaScript中的逻辑表达式的返回值也不只是简单的true/false,而是通过特定的规则返回操作数中的某一个或者是返回true/false,规则如下:
- 逻辑
与
运算(&&)表达式:expr1 && expr2
如果Boolean(expr1)为false,则返回expr1;否则返回expr2;相当于Boolean(expr1)?expr2:expr1
- 逻辑
或
运算(||)表达式:expr1 || expr2
如果Boolean(expr1)为true, 则返回expr1;否则返回expr2; 相当于Boolean(expr1)?expr1:expr2
- 逻辑
非
运算 (!)表达式:!expr
如果Boolean(expr)为true,则返回false; 否则返回true
一些便捷的写法
利用上述的特性,我们可以用更简洁的方式完成很多以前用if-else和cond?a:b完成的任务,以下是个例子:
function Car(options){ //用if-else if(!options){ options = {}; } //用cond?a:b options = options?options:{}; //巧用逻辑运算符 options = options || {}; }
注意事项
- 当操作数是数字、或者字符串时,要格外小心,因为Boolean(expr)为false的情形中包含了0, -0, 空字符串这几个特殊的值,很多时候我们只是希望将null和undefined当作false,而一切数字和字符串都当成true;这个问题对于对象类型的操作数无须考虑