## 13.非值`undefined`和`null`
> 原文: [http://exploringjs.com/impatient-js/ch_undefined-null.html](http://exploringjs.com/impatient-js/ch_undefined-null.html)
>
> 貢獻者:[飛龍](https://github.com/wizardforcel)
許多編程語言都有一個名為`null`的“非值”。它表示變量當前未指向對象。例如,尚未初始化時。
相比之下,JavaScript 有兩個:`undefined`和`null`。
### 13.1。 `undefined`與`null`
兩個值都非常相似,并且通常可互換使用。因此它們的區別是微妙的。語言本身具有以下區別:
* `undefined`表示“未初始化”(例如變量)或“不存在”(例如對象的屬性)。
* `null`表示“故意沒有任何對象值”([參考語言規范](https://tc39.github.io/ecma262/#sec-null-value))。
程序員可以做出以下區分:
* `undefined`是語言使用的非值(當某些內容未初始化時)。
* `null`表示“明確關閉”。也就是說,它有助于實現一種類型,既包含有意義的值又包含代表“無意義的值”的元值。這種類型在函數式編程中稱為[*可選類型*或*可能類型*](https://en.wikipedia.org/wiki/Option_type) 。
### 13.2。 `undefined`和`null`的位置
以下小節描述了`undefined`和`null`在語言中的位置。我們將遇到幾種機制,本書稍后將對此進行更詳細的解釋。
#### 13.2.1。 `undefined`的位置
未初始化的變量`myVar`:
```js
let myVar;
assert.equal(myVar, undefined);
```
未提供的參數`x`:
```js
function func(x) {
return x;
}
assert.equal(func(), undefined);
```
缺失屬性`.unknownProp`:
```js
const obj = {};
assert.equal(obj.unknownProp, undefined);
```
如果沒有通過`return`運算符顯式指定函數的結果,JavaScript 會為您返回`undefined`:
```js
function func() {}
assert.equal(func(), undefined);
```
#### 13.2.2。 `null`的位置
對象的原型是一個對象,或者在原型鏈的末尾,是`null`。 `Object.prototype`沒有原型:
```js
> Object.getPrototypeOf(Object.prototype)
null
```
如果將正則表達式(例如`/a/`)與字符串(例如`'x'`)匹配,則可以獲得具有匹配數據的對象(如果匹配成功)或`null`(如果匹配失敗):
```js
> /a/.exec('x')
null
```
[JSON 數據格式](ch_json.html)不支持`undefined`,僅支持`null`:
```js
> JSON.stringify({a: undefined, b: null})
'{"b":null}'
```
### 13.3。檢查`undefined`或`null`
檢查:
`x`有值嗎?
```js
if (x === null) ···
if (x === undefined) ···
```
`x`是`undefined`還是`null`?
```js
if (x !== undefined && x !== null) {
// ···
}
if (x) { // truthy?
// x is neither: undefined, null, false, 0, NaN, ''
}
```
*真值*的意思是“如果強制轉換為布爾值則為`true`”。*假值*的意思是“如果強制轉換為布爾值則為`false`”。在[布爾值](ch_booleans.html#falsiness-truthiness)的章節中正確解釋了這兩個概念。
### 13.4。 `undefined`和`null`沒有屬性
`undefined`和`null`是兩個唯一的 JavaScript 值,如果您嘗試讀取屬性,則會獲得異常。為了探索這種現象,讓我們使用以下函數,它讀取(“獲取”)屬性`.foo`并返回結果。
```js
function getFoo(x) {
return x.foo;
}
```
如果我們將`getFoo()`應用于各種值,我們可以看到它只對`undefined`和`null`失敗:
```js
> getFoo(undefined)
TypeError: Cannot read property 'foo' of undefined
> getFoo(null)
TypeError: Cannot read property 'foo' of null
> getFoo(true)
undefined
> getFoo({})
undefined
```
### 13.5。 `undefined`和`null`的歷史
在 Java(它激發了 JavaScript 的許多方面)中,初始化值取決于變量的靜態類型:
* 具有對象類型的變量用`null`初始化。
* 每個原始類型都有自己的初始化值。例如,`int`變量用`0`初始化。
在 JavaScript 中,每個變量都可以包含對象值和原始值。因此,如果`null`表示“不是對象”,JavaScript 還需要一個初始化值,這意味著“既不是對象也不是原始值”。初始化值為`undefined`。
 **測驗**
參見[測驗應用程序](ch_quizzes-exercises.html#quizzes)。
- I.背景
- 1.關于本書(ES2019 版)
- 2.常見問題:本書
- 3. JavaScript 的歷史和演變
- 4.常見問題:JavaScript
- II.第一步
- 5.概覽
- 6.語法
- 7.在控制臺上打印信息(console.*)
- 8.斷言 API
- 9.測驗和練習入門
- III.變量和值
- 10.變量和賦值
- 11.值
- 12.運算符
- IV.原始值
- 13.非值undefined和null
- 14.布爾值
- 15.數字
- 16. Math
- 17. Unicode - 簡要介紹(高級)
- 18.字符串
- 19.使用模板字面值和標記模板
- 20.符號
- V.控制流和數據流
- 21.控制流語句
- 22.異常處理
- 23.可調用值
- VI.模塊化
- 24.模塊
- 25.單個對象
- 26.原型鏈和類
- 七.集合
- 27.同步迭代
- 28.數組(Array)
- 29.類型化數組:處理二進制數據(高級)
- 30.映射(Map)
- 31. WeakMaps(WeakMap)
- 32.集(Set)
- 33. WeakSets(WeakSet)
- 34.解構
- 35.同步生成器(高級)
- 八.異步
- 36. JavaScript 中的異步編程
- 37.異步編程的 Promise
- 38.異步函數
- IX.更多標準庫
- 39.正則表達式(RegExp)
- 40.日期(Date)
- 41.創建和解析 JSON(JSON)
- 42.其余章節在哪里?