js 布尔运算符 - 图1

概述

布尔运算符用于将表达式转为布尔值,一共包含 3 个运算符:

  • 取反运算符:!
  • 且运算符:&&
  • 或运算符:||

取反运算符(!)

取反运算符是一个感叹号,用于将布尔值变为相反值,即**true**变成**false****false**变成**true**

  1. !true // false
  2. !false // true

对于非布尔值,取反运算符会将其转为布尔值。可以这样记忆,以下六个值取反后为true,其他值都为false

  • undefined
  • null
  • false
  • 0
  • NaN
  • 空字符串(''
  1. !undefined // true
  2. !null // true
  3. !0 // true
  4. !NaN // true
  5. !"" // true
  6. !54 // false
  7. !'hello' // false
  8. ![] // false
  9. !{} // false

上面代码中,不管什么类型的值,经过取反运算后,都变成了布尔值。

如果对一个值连续做两次取反运算,等于将其转为对应的布尔值,与Boolean函数的作用相同。这是一种常用的类型转换的写法。

  1. !!x
  2. // 等同于
  3. Boolean(x)

上面代码中,不管x是什么类型的值,经过两次取反运算后,变成了与Boolean函数结果相同的布尔值。所以,两次取反就是将一个值转为布尔值的简便写法。

且运算符(&&)

且运算符(&&)往往用于多个表达式的求值。

它的运算规则是:如果第一个运算子的布尔值为**true**,则返回第二个运算子的值(注意是值,不是布尔值);如果第一个运算子的布尔值为**false**,则直接返回第一个运算子的值,且不再对第二个运算子求值

  1. 't' && '' // ""
  2. 't' && 'f' // "f"
  3. 't' && (1 + 2) // 3
  4. '' && 'f' // ""
  5. '' && '' // ""
  6. var x = 1;
  7. (1 - 1) && ( x += 1) // 0
  8. x // 1

上面代码的最后一个例子,由于且运算符的第一个运算子的布尔值为false,则直接返回它的值0,而不再对第二个运算子求值,所以变量x的值没变。

这种跳过第二个运算子的机制,被称为“短路”。有些程序员喜欢用它取代if结构,比如下面是一段if结构的代码,就可以用且运算符改写。

  1. if (i) {
  2. doSomething();
  3. }
  4. // 等价于
  5. i && doSomething();

上面代码的两种写法是等价的,但是后一种不容易看出目的,也不容易除错,建议谨慎使用。

且运算符可以多个连用,这时返回第一个布尔值为false的表达式的值。如果所有表达式的布尔值都为true,则返回最后一个表达式的值。

  1. true && 'foo' && '' && 4 && 'foo' && true
  2. // ''
  3. 1 && 2 && 3
  4. // 3

上面代码中,例一里面,第一个布尔值为false的表达式为第三个表达式,所以得到一个空字符串。例二里面,所有表达式的布尔值都是true,所以返回最后一个表达式的值3

或运算符(||)

或运算符(||)也用于多个表达式的求值。它的运算规则是:如果第一个运算子的布尔值为**true**,则返回第一个运算子的值,且不再对第二个运算子求值;如果第一个运算子的布尔值为**false**,则返回第二个运算子的值。

  1. 't' || '' // "t"
  2. 't' || 'f' // "t"
  3. '' || 'f' // "f"
  4. '' || '' // ""

短路规则对这个运算符也适用。

  1. var x = 1;
  2. true || (x = 2) // true
  3. x // 1

上面代码中,或运算符的第一个运算子为true,所以直接返回true,不再运行第二个运算子。所以,x的值没有改变。这种只通过第一个表达式的值,控制是否运行第二个表达式的机制,就称为“短路”(short-cut)。

或运算符可以多个连用,这时返回第一个布尔值为true的表达式的值。如果所有表达式都为false,则返回最后一个表达式的值。

  1. false || 0 || '' || 4 || 'foo' || true
  2. // 4
  3. false || 0 || ''
  4. // ''

上面代码中,例一里面,第一个布尔值为true的表达式是第四个表达式,所以得到数值4。例二里面,所有表达式的布尔值都为false,所以返回最后一个表达式的值。

或运算符常用于为一个变量设置默认值。

  1. function saveText(text) {
  2. text = text || '';
  3. // ...
  4. }
  5. // 或者写成
  6. saveText(this.text || '')

上面代码表示,如果函数调用时,没有提供参数,则该参数默认设置为空字符串。

练习

  • 用一个变量保存成绩,输出该成绩是否及格(true 或 false)
  1. var score = 59;
  2. console.log(score >= 60); // false
  • 用一个变量保存年份,得到该年份 2 月的天数
  1. var year = 2020;
  2. var result = (year % 4 === 0 && year % 100) || year % 400;
  3. result && console.log('今年是闰年 二月的天数为29天'); // 执行
  4. result || console.log('今年是平年 二月的天数为28天');
  5. // 判闰年的逻辑:四年一闰,百年不闰,四百年一闰。
  • 利息计算器

设置变量,分别存放本金、月数、年利率,计算利息

如果本金存放量超过了10万,年利率上浮20%(比如,年利率为4%,上浮后的年利率 4% * 1.2)

  1. var capital = 1000000, // 本金100万
  2. months = 24, // 存放两年
  3. rate = 0.04; // 4%的年利率
  4. capital > 100000 && (rate = rate * 1.2);
  5. var earnMoney = capital * rate / 12 * months;
  6. console.log(earnMoney); // 96000