第 10 章. 布尔值
目录
购买本书
(广告,请不要屏蔽。)

第 10 章. 布尔值

原始布尔类型包含值 truefalse

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

转换为布尔值

值的转换为布尔值的方式如下:

转换为布尔值

undefined

false

null

false

布尔值

与输入相同(无需转换)

数字

0, NaNfalse

其他数字 → true

字符串

''false

其他字符串 → true

对象

true(始终如此!)

手动转换为布尔值

任何值都可以通过三种方式转换为布尔值:

Boolean(value)

(作为函数调用,而不是作为构造函数)

value ? true : false

!!value

单个“非”转换为取反的布尔值;使用两次进行非取反转换。

我更喜欢 Boolean(),因为它更具描述性。以下是一些示例:

> Boolean(undefined)
false
> Boolean(null)
false

> Boolean(0)
false
> Boolean(1)
true
> Boolean(2)
true

> Boolean('')
false
> Boolean('abc')
true
> Boolean('false')
true

真值和假值

在 JavaScript 需要布尔值的地方,您可以提供任何类型的值,它会自动转换为布尔值。因此,JavaScript 中有两组值:一组转换为 false,而另一组转换为 true。这些集合称为 假值真值根据上表,以下是所有假值:

  • undefined, null
  • 布尔值:false
  • 数字:0, NaN
  • 字符串:''

所有其他值(包括所有对象,即使是空对象、空数组和 new Boolean(false))都是真值。因为 undefinednull 是假值,所以您可以使用 if 语句来检查变量 x 是否有值

if (x) {
    // x has a value
}

需要注意的是,前面的检查将所有假值解释为“没有值”,而不仅仅是 undefinednull。但是,如果您能够接受这种限制,那么您就可以使用一种紧凑且已建立的模式。

陷阱:所有对象都是真值

所有对象都是真值:

> Boolean(new Boolean(false))
true
> Boolean([])
true
> Boolean({})
true

这与对象转换为数字或字符串的方式不同,在转换为数字或字符串时,您可以通过实现 valueOf()toString() 方法来控制结果:

> Number({ valueOf: function () { return 123 } })
123
> String({ toString: function () { return 'abc' } })
'abc'

历史:为什么对象始终为真值?

转换为布尔值的方式有所不同,这是历史原因造成的。对于 ECMAScript 1,决定不允许对象配置该转换(例如,通过 toBoolean() 方法)。理由是布尔运算符 ||&& 保留其操作数的值。因此,如果您链接这些运算符,则可能会多次检查相同值的真假性。对于基元类型来说,这种检查成本很低,但如果对象能够配置其转换为布尔值的方式,则对于对象来说成本会很高。ECMAScript 1 通过使对象始终为真值来避免这种成本。

逻辑运算符

在本节中,我们将介绍 And (&&)、Or (||) 和 Not (!) 逻辑运算符的基础知识。

二元逻辑运算符:And (&&) 和 Or (||)

二元逻辑运算符是:

保留值的

它们始终返回其中一个操作数,且保持不变

> 'abc' || 123
'abc'
> false || 123
123
短路的

如果第一个操作数已经确定了结果,则不会计算第二个操作数。 例如(console.log 的结果是 undefined):

> true || console.log('Hello')
true
> false || console.log('Hello')
Hello
undefined

这对于运算符来说是不常见的行为。通常,所有操作数都会在调用运算符之前进行计算(就像函数一样)。

逻辑与 (&&)

如果第一个操作数可以转换为 false,则返回它。否则,返回第二个操作数:

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

逻辑或 (||)

如果第一个操作数可以转换为 true,则返回它。否则,返回第二个操作数:

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

示例 1:参数的默认值

函数 saveText() 的参数 text 是可选的,如果省略了该参数,则应为空字符串:

function saveText(text) {
    text = text || '';
    ...
}

这是 || 作为默认运算符的最常见用法。有关可选参数的更多信息,请参阅可选参数

示例 2:属性的默认值

对象 options 可能有也可能没有属性 title。如果缺少该属性,则在设置标题时应使用值 'Untitled'

setTitle(options.title || 'Untitled');

示例 3:函数结果的默认值

函数 countOccurrences 统计 regexstr 中匹配的次数

function countOccurrences(regex, str) {
    // Omitted: check that /g is set for `regex`
    return (str.match(regex) || []).length;
}

问题是 match()(请参阅String.prototype.match: 捕获组或返回所有匹配的子字符串)要么返回一个数组,要么返回 null。由于使用了 ||,因此在后一种情况下会使用默认值。因此,您可以在两种情况下安全地访问属性 length

逻辑非 (!)

逻辑非运算符 ! 将其操作数转换为布尔值,然后对其取反:

> !true
false
> !43
false
> !''
true
> !{}
false

相等运算符、排序运算符

以下运算符将在其他地方介绍

函数 Boolean

函数 Boolean 可以通过两种方式调用

Boolean(value)

作为普通函数,它将 value 转换为原始布尔值(请参阅转换为布尔值

> Boolean(0)
false
> typeof Boolean(false)  // no change
'boolean'
new Boolean(bool)

作为构造函数,它创建一个新的 Boolean 实例(请参阅基元类型的包装对象),该实例包装 bool(在将其转换为布尔值之后)。例如

> typeof new Boolean(false)
'object'

前一种调用方式更为常见。

下一页:11. 数字