
概述
布尔运算符用于将表达式转为布尔值,一共包含 3 个运算符:
- 取反运算符:
! - 且运算符:
&& - 或运算符:
||
取反运算符(!)
取反运算符是一个感叹号,用于将布尔值变为相反值,即**true**变成**false**,**false**变成**true**。
!true // false!false // true
对于非布尔值,取反运算符会将其转为布尔值。可以这样记忆,以下六个值取反后为true,其他值都为false。
undefinednullfalse0NaN- 空字符串(
'')
!undefined // true!null // true!0 // true!NaN // true!"" // true!54 // false!'hello' // false![] // false!{} // false
上面代码中,不管什么类型的值,经过取反运算后,都变成了布尔值。
如果对一个值连续做两次取反运算,等于将其转为对应的布尔值,与Boolean函数的作用相同。这是一种常用的类型转换的写法。
!!x// 等同于Boolean(x)
上面代码中,不管x是什么类型的值,经过两次取反运算后,变成了与Boolean函数结果相同的布尔值。所以,两次取反就是将一个值转为布尔值的简便写法。
且运算符(&&)
且运算符(&&)往往用于多个表达式的求值。
它的运算规则是:如果第一个运算子的布尔值为**true**,则返回第二个运算子的值(注意是值,不是布尔值);如果第一个运算子的布尔值为**false**,则直接返回第一个运算子的值,且不再对第二个运算子求值。
't' && '' // ""'t' && 'f' // "f"'t' && (1 + 2) // 3'' && 'f' // ""'' && '' // ""var x = 1;(1 - 1) && ( x += 1) // 0x // 1
上面代码的最后一个例子,由于且运算符的第一个运算子的布尔值为false,则直接返回它的值0,而不再对第二个运算子求值,所以变量x的值没变。
这种跳过第二个运算子的机制,被称为“短路”。有些程序员喜欢用它取代if结构,比如下面是一段if结构的代码,就可以用且运算符改写。
if (i) {doSomething();}// 等价于i && doSomething();
上面代码的两种写法是等价的,但是后一种不容易看出目的,也不容易除错,建议谨慎使用。
且运算符可以多个连用,这时返回第一个布尔值为false的表达式的值。如果所有表达式的布尔值都为true,则返回最后一个表达式的值。
true && 'foo' && '' && 4 && 'foo' && true// ''1 && 2 && 3// 3
上面代码中,例一里面,第一个布尔值为false的表达式为第三个表达式,所以得到一个空字符串。例二里面,所有表达式的布尔值都是true,所以返回最后一个表达式的值3。
或运算符(||)
或运算符(||)也用于多个表达式的求值。它的运算规则是:如果第一个运算子的布尔值为**true**,则返回第一个运算子的值,且不再对第二个运算子求值;如果第一个运算子的布尔值为**false**,则返回第二个运算子的值。
't' || '' // "t"'t' || 'f' // "t"'' || 'f' // "f"'' || '' // ""
短路规则对这个运算符也适用。
var x = 1;true || (x = 2) // truex // 1
上面代码中,或运算符的第一个运算子为true,所以直接返回true,不再运行第二个运算子。所以,x的值没有改变。这种只通过第一个表达式的值,控制是否运行第二个表达式的机制,就称为“短路”(short-cut)。
或运算符可以多个连用,这时返回第一个布尔值为true的表达式的值。如果所有表达式都为false,则返回最后一个表达式的值。
false || 0 || '' || 4 || 'foo' || true// 4false || 0 || ''// ''
上面代码中,例一里面,第一个布尔值为true的表达式是第四个表达式,所以得到数值4。例二里面,所有表达式的布尔值都为false,所以返回最后一个表达式的值。
或运算符常用于为一个变量设置默认值。
function saveText(text) {text = text || '';// ...}// 或者写成saveText(this.text || '')
上面代码表示,如果函数调用时,没有提供参数,则该参数默认设置为空字符串。
练习
- 用一个变量保存成绩,输出该成绩是否及格(true 或 false)
var score = 59;console.log(score >= 60); // false
- 用一个变量保存年份,得到该年份 2 月的天数
var year = 2020;var result = (year % 4 === 0 && year % 100) || year % 400;result && console.log('今年是闰年 二月的天数为29天'); // 执行result || console.log('今年是平年 二月的天数为28天');// 判闰年的逻辑:四年一闰,百年不闰,四百年一闰。
- 利息计算器
设置变量,分别存放本金、月数、年利率,计算利息
如果本金存放量超过了10万,年利率上浮20%(比如,年利率为4%,上浮后的年利率 4% * 1.2)
var capital = 1000000, // 本金100万months = 24, // 存放两年rate = 0.04; // 4%的年利率capital > 100000 && (rate = rate * 1.2);var earnMoney = capital * rate / 12 * months;console.log(earnMoney); // 96000
