# 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>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://anjia1.gitbook.io/web/js/data-type/primitive/boolean.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
