> For the complete documentation index, see [llms.txt](https://anjia1.gitbook.io/web/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://anjia1.gitbook.io/web/js/data-type/primitive/boolean.md).

# 3. Boolean

## 1. 通用知识

在计算机科学中，Boolean 数据类型是一种具有两个可能值之一的数据类型，通常表示为 true 和 false，旨在表示逻辑和布尔代数的两个真值（truth value，有时也称 logical value）。它是以英国数学家、哲学家、逻辑学家 George Boole 的名字命名的，他在 19 世纪中叶首次定义了逻辑代数系统。

Boolean 类型主要和条件语句关联。条件语句根据布尔条件的计算结果的真假来改变控制流，从而允许不同的操作。Boolean 数据类型是更通用的逻辑数据类型的特例，逻辑并不总是布尔值，详见[概率逻辑](https://en.wikipedia.org/wiki/Probabilistic_logic)。

在大多数编程语言中，即便是那些没有明确 Boolean 类型的语言（可以用其它数据类型来表示真/假值），它们都支持 Boolean 代数运算，比如：

* 合取：AND, &, \*
* 析取：OR, |, +
* 等价：EQV, =, ==
* 异或/非等价：XOR, NEQV, ^, !=
* 否定：NOT, \~, !

## 2. 原始值

Boolean 类型表示逻辑实体，它有两个值：true 和 false。

## 3. 对象包装器

Boolean 对象是 Boolean 值的对象包装器。

### 3.1 构造器

1. `new Boolean()` 返回对象，搭配 new 关键字作为构造函数用
2. `Boolean()` 返回布尔值，直接当函数用可执行类型转换

### 3.2 对象的实例方法

1. `valueOf()` 返回 Boolean 原始值
2. `toString()` 返回字符串

```javascript
// 不同实例化方法对应的 typeof 类型
let bVal = true;          // 字面量
let bFunc = Boolean();    // 函数
let bObj = new Boolean(); // new

typeof bVal === 'boolean';   // true
typeof bFunc === 'boolean';  // true
typeof bObj === 'object';    // true

// 用构造函数得到对象，以及相应的实例方法
let foo = new Boolean();
foo.valueOf();   // false
foo.toString();  // "false"
```

## 4. 注意事项

### 4.1 Boolean 对象的初始值

当参数是以下 8 种情况之一时，对象的初始值是 false。

* 空参数, 空字符串, null, undefined（4种）
* false
* 0, -0, NaN（3种）

否则，对象的初始值都是 true，包括字符串 'false' 和任意对象，诸如空数组 \[]、空对象 {}，以及值是 false 的 Boolean 对象，比如 `new Boolean()`。

```javascript
let bar = new Boolean('false');
console.log(bar.valueOf());  // true

let foo = new Boolean([]);
console.log(foo.valueOf());  // true

let baz = new Boolean({});
console.log(baz.valueOf());  // true

new Boolean( new Boolean() ).valueOf();   // true
```

### 4.2 `if (对象)`

不要将 Boolean 类型的 true/false 值和 Boolean 对象的 true/false 值搞混了。前者是纯纯的原始值，后者是“对象”的值。

任何值不是 undefined 和 null 的对象（包括值为 false 的 Boolean 对象），在传给条件语句的时候，都会被解析成 true。如下：

```javascript
if([]){
  console.log('[] is true.');  // 会输出 [] is true.
}
if({}){
  console.log('{} is true.');  // 会输出 {} is true.
}
let bObj = new Boolean(false);
if(bObj){
  console.log('new Boolean(false) is true');  // 会输出 new Boolean(false) is true
}
```

所以，不要使用 Boolean 对象替代 Boolean 原始值。

#### 插播：

`if([])` 是 true，`if([]==false)` 也是 true，为什么？

```javascript
if([] == false) {
  console.log('[]==false is true');   // 会输出 []==false is true
}
```

当将对象和 Boolean 原始值进行松散比较（==）时，需要了解实际比较的内容。`[] == false` 比较的是 `[]` 的值和 false，即 `[].toString()` 和 false，即 `"" == false`。

> 这类知识详见[《1.4 类型转换》](/web/js/data-type/conversion.md)，这里就不展开了。

### 4.3 转成 Boolean 值

如果要把一个非 Boolean 值转成 Boolean 值，不推荐使用 Boolean 对象。

可以使用 Boolean 函数或者双感叹号，它们都会返回 Boolean 类型。

* `new Boolean()` 返回对象，它有自己唯一的内存地址
* `Boolean()` 返回 Boolean 原始值

```javascript
var x = (new Boolean(expression)).valueOf();  // 不推荐
var x = Boolean(expression);  // 推荐
var x = !!(expression);       // 推荐
```

## 5. 总结

这部分介绍了 Boolean 类型以及它的两个值 true 和 false，也简单介绍了 Boolean 值的对象包装器 Boolean 对象。

需要注意的是，不建议用 Boolean 对象替代 Boolean 原始值，因为 Boolean 对象的初始值和 `if(对象)` 的实际行为可能会和大家的第一感觉有出入，从而导致没有必要的 bug。

但 Boolean 值的类型转换，包括显式的和隐式的，尤其是当它作为条件语句时的场景，需要理解透彻并熟练应用。

## 6. 主要参考

* <https://en.wikipedia.org/wiki/Boolean_data_type>
* <https://developer.mozilla.org/en-US/docs/Glossary/Boolean>
* <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean>
