布尔运算符

1、概述

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

取反运算符:!
且运算符:&&
或运算符:||
三元运算符:?:

2、取反运算符(!)

  • 取反运算符是一个感叹号,用于将布尔值变为相反值。
  • 对于非布尔值,取反运算符会将其转为布尔值。
  • 不管什么类型的值,经过取反运算后,都变成了布尔值。
  • 如果对一个值连续做两次取反运算,等于将其转为对应的布尔值,与Boolean函数的作用相同
// true变成false,false变成true
!true // false
!false // true

// 非布尔值,以下六个值取反后为true,其他值都为false
!undefined // true
!null // true
!0 // true
!NaN // true
!"" // true

!54 // false
!'hello' // false
![] // false
!{} // false

// 不管x是什么类型的值,经过两次取反运算后,变成了与Boolean函数结果相同的布尔值
// 两次取反就是将一个值转为布尔值的简便写法
!!x
// 等同于
Boolean(x)

3、且运算符(&&)

  • 且运算符(&&)往往用于多个表达式的求值
  • 如果第一个运算子的布尔值为true,则返回第二个运算子的值(注意是值,不是布尔值)。
  • 如果第一个运算子的布尔值为false,则直接返回第一个运算子的值,且不再对第二个运算子求值。
  • 跳过第二个运算子的机制,被称为“短路”。
  • 且运算符可以多个连用,这时返回第一个布尔值为false的表达式的值。
  • 如果所有表达式的布尔值都为true,则返回最后一个表达式的值。
// 多个表达式的求值
't' && '' // ""
't' && 'f' // "f"
't' && (1 + 2) // 3
'' && 'f' // ""
'' && '' // ""

// 且运算符的第一个运算子的布尔值为false,则直接返回它的值0
// 而不再对第二个运算子求值,所以变量x的值没变。
var x = 1;
(1 - 1) && ( x += 1) // 0
x // 1

// 一段if结构的代码,就可以用且运算符改写
if (i) {
  doSomething();
}
// 等价于
i && doSomething(); // 不易除错,建议谨慎使用。


// 第一个布尔值为false的表达式为第三个表达式,所以得到一个空字符串
true && 'foo' && '' && 4 && 'foo' && true
// ''

// 所有表达式的布尔值都是true,所以返回最后一个表达式的值3
1 && 2 && 3
// 3

4、或运算符(||)

  • 或运算符(||)也用于多个表达式的求值,或运算符常用于为一个变量设置默认值
  • 如果第一个运算子的布尔值为true,则返回第一个运算子的值,且不再对第二个运算子求值。
  • 如果第一个运算子的布尔值为false,则返回第二个运算子的值。
  • 只通过第一个表达式的值,控制是否运行第二个表达式的机制,就称为“短路”(short-cut)。
  • 或运算符可以多个连用,这时返回第一个布尔值为true的表达式的值。
  • 如果所有表达式都为false,则返回最后一个表达式的值。
// 多个表达式的求值
't' || '' // "t"
't' || 'f' // "t"
'' || 'f' // "f"
'' || '' // ""

// 短路:第一个运算子为`true`,直接返回`true`,x的值没有改变
var x = 1;
true || (x = 2) // true
x // 1

// 第一个布尔值为true的表达式是第四个表达式,所以得到数值4
false || 0 || '' || 4 || 'foo' || true
// 4

// 所有表达式的布尔值都为false,所以返回最后一个表达式的值。
false || 0 || ''
// ''

// 如果函数调用时,没有提供参数,则该参数默认设置为空字符串
function saveText(text) {
  text = text || '';
  // ...
}

// 或者写成
saveText(this.text || '')

5、三元条件运算符(?:)

  • 三元条件运算符由问号(?)和冒号(:)组成,分隔三个表达式,JavaScript 语言唯一一个需要三个运算子的运算符。
  • 如果第一个表达式的布尔值为true,则返回第二个表达式的值,否则返回第三个表达式的值。
  • 三元条件表达式if...else语句(无返回值)具有同样表达效果,前者可以表达的,后者也能表达。
// t和0的布尔值分别为true和false,所以分别返回第二个和第三个表达式的值。
't' ? 'hello' : 'world' // "hello"
0 ? 'hello' : 'world' // "world"

// 需要返回值的场合,只能使用三元条件表达式,不能使用if..else
// console.log方法的参数必须是一个表达式,这时就只能使用三元条件表达式
console.log(true ? 'T' : 'F');