12.布尔值

基本类型布尔值 包含两个值 - falsetrue

> typeof false
'boolean'
> typeof true
'boolean'

12.1 转换为布尔值

这三种方法可以将任意值x转换为布尔值。

  • Boolean(x) 最具描述性;推荐。
  • x ? true : false 使用条件运算符。
  • !!x 使用逻辑非运算符(!)。此运算符将其操作数强制转换为布尔值。它被第二次应用来获得非否定的结果。

表 4 描述了各种值如何转换为布尔值。

表 4:将值转换为布尔值

x Boolean(x)
undefined false
null false
布尔值 x(无变化)
数值 0 → falseNaN → false
其他数字 → true
字符串值 '' → false
其他字符串 → true
对象值 总是true

12.2 真值和假值

在 JavaScript 中,如果您读取了不存在的内容(例如缺失参数或缺失属性),则通常会得到undefined。在这些情况下,存在性检查相当于将值与undefined进行比较。例如,以下代码检查对象obj是否具有属性.prop

if (obj.prop !== undefined) {
  // obj has property .prop
}

为简化此检查,我们可以使用一个事实,if语句始终将其条件值转换为布尔值:

if ('abc') { // true, if converted to boolean
  console.log('Yes!');
}

因此,我们可以使用以下代码来检查obj.prop是否存在。这与undefined相比不太精确,但也更短:

if (obj.prop) {
  // obj has property .prop
}

这种简化的检查非常流行,引入了以下两个名称:

  • 如果它在转换为布尔值时是true,则称为真值
  • 如果它在转换为布尔值时是false,则称为假值

查询表 4,我们可以列出一个详尽的假值列表:

  • undefinednull
  • 布尔:false
  • 数字:0NaN
  • 字符串:''

所有其他值(包括所有 对象)都是真值:

> Boolean('abc')
true
> Boolean([])
true
> Boolean({})
true

12.2.1 陷阱:真实性检查是不精确的

真实性检查有一个陷阱:它们不是很精确。考虑前面的例子:

if (obj.prop) {
  // obj has property .prop
}

如果出现以下情况,则跳过if语句的正文:

  • 缺少obj.prop(在这种情况下,JavaScript 返回undefined)。

但是,如果出现以下情况,也会跳过它:

  • obj.propundefined
  • obj.prop是任何其他假值(null0''等)。

在实践中,这很少会引起问题,但你必须意识到这个陷阱。

12.2.2 检查真实性或虚假性

if (x) {
  // x is truthy
}
if (!x) {
  // x is falsy
}
if (x) {
  // x is truthy
} else {
  // x is falsy
}
const result = x ? 'truthy' : 'falsy';

最后一行中使用的条件运算符将在 第五章:控制流和数据流 中解释。

12.2.3 用例:是否提供了参数?

真值检查通常用于确定函数的调用者是否提供了参数:

function func(x) {
  if (!x) {
    throw new Error('Missing parameter x');
  }
  // ···
}

从好的方面来说,这种模式已经建立并且很短。它正确地为undefinednull抛出错误。

而另一面,有前面提到的陷阱:代码也会对所有其他假值抛出错误。

另一种方法是检查undefined

if (x === undefined) {
  throw new Error('Missing parameter x');
}

12.2.4 用例:存在属性吗?

真实性检查通常也用于确定属性是否存在:

function readFile(fileDesc) {
  if (!fileDesc.path) {
    throw new Error('Missing property: .path');
  }
  // ···
}
readFile({ path: 'foo.txt' }); // no error

这种模式也已建立,并且有一个常见的警告:它不仅会在属性丢失时抛出,而且如果它存在并且具有任何假值。

如果你真的想检查属性是否存在,你必须使用in运算符:

if (! ('path' in fileDesc)) {
  throw new Error('Missing property: .path');
}

练习:真实性

exercises/booleans/truthiness_exrc.js

12.3 条件运算符(? :

条件运算符是if语句的表达式版本。它的语法是:

«condition» ? «thenExpression» : «elseExpression»

求值如下:

  • 如果condition是真值,求值并返回thenExpression
  • 否则,求值并返回elseExpression

条件运算符也称为三元运算符 ,因为它有三个操作数。

> true ? 'yes' : 'no'
'yes'
> false ? 'yes' : 'no'
'no'
> '' ? 'yes' : 'no'
'no'

下面的代码演示了,通过条件选择thenelse两个分支中的任何一个 - 只求值该分支。另一个分支不是。

const x = (true ? console.log('then') : console.log('else'));
// Output:
// 'then'

12.4 二元逻辑运算符:和(x && y),或(x || y

运算符&&||值保留短路 的。那是什么意思?

值保留 意味着操作数被解释为布尔值,但返回值不变:

> 12 || 'hello'
12
> 0 || 'hello'
'hello'

短路 表示:如果第一个操作数已经确定了结果,则不求值第二个操作数。延迟求值其操作数的唯一其他运算符是条件运算符:通常,在执行操作之前求值所有操作数。

例如,如果第一个操作数是假值,则逻辑和(&&)不会计算其第二个操作数:

const x = false && console.log('hello');
// No output

如果第一个操作数是真值,则执行console.log()

const x = true && console.log('hello');
// Output:
// 'hello'

12.4.1 逻辑和(x && y

表达式a && b(“ab”)的求值如下:

  • 求值a
  • 结果是假值吗?把它返回。
  • 否则,求值b并返回结果。

换句话说,以下两个表达式大致相同:

a && b
!a ? a : b

例子:

> false && true
false
> false && 'abc'
false
> true && false
false
> true && 'abc'
'abc'
> '' && 'abc'
''

12.4.2 逻辑或(||

表达式a || b(“ab”)的求值如下:

  • 求值a
  • 结果是真值?把它返回。
  • 否则,求值b并返回结果。

换句话说,以下两个表达式大致相同:

a || b
a ? a : b

例子:

> true || false
true
> true || 'abc'
true
> false || true
true
> false || 'abc'
'abc'
> 'abc' || 'def'
'abc'

12.4.3 通过逻辑或(||)的默认值

有时您会收到一个值,如果它不是nullundefined,则只想使用它。否则,您希望使用默认值作为后备。您可以通过||运算符执行此操作:

const valueToUse = valueReceived || defaultValue;

以下代码显示了一个真实示例:

function countMatches(regex, str) {
  const matchResult = str.match(regex); // null or Array
  return (matchResult || []).length;
}

如果str内有regex的一个或多个匹配项,则.match()返回一个数组。如果没有匹配,则很遗憾地返回null(而不是空数组)。我们通过||运算符来解决这个问题。

练习:通过或运算符(|| 的默认值

exercises/booleans/default_via_or_exrc.js

12.5 逻辑非(!

表达式!x(“Not x”)的求值如下:

  • 求值x
  • 这是真值?返回false
  • 否则,返回true
> !false
true
> !true
false
> !0
true
> !123
false
> !''
true
> !'abc'
false
下一节:本章介绍 JavaScript 的单一类型数字,number。