## 15.數字
> 原文: [http://exploringjs.com/impatient-js/ch_numbers.html](http://exploringjs.com/impatient-js/ch_numbers.html)
>
> 貢獻者:[飛龍](https://github.com/wizardforcel)
本章介紹 JavaScript 的單一類型數字,`number`。
### 15.1。 JavaScript 只有浮點數
您可以在 JavaScript 中表示整數和浮點數:
```js
98
123.45
```
但是,所有數字只有一種類型:它們都是*雙精度*,根據 IEEE 浮點運算標準(IEEE 754)實現的 64 位浮點數。
整數只是沒有小數部分的浮點數:
```js
> 98 === 98.0
true
```
請注意,在大多數情況下,大多數 JavaScript 引擎通常都能夠使用實際整數,并具有所有相關的性能和存儲大小優勢。
### 15.2。數字字面值
讓我們檢查數字的字面值。
#### 15.2.1。整數字面值
幾個*整數字面值*讓你用各種基數表示整數:
```js
// Binary (base 2)
assert.equal(0b11, 3);
// Octal (base 8)
assert.equal(0o10, 8);
// Decimal (base 10):
assert.equal(35, 35);
// Hexadecimal (base 16)
assert.equal(0xE7, 231);
```
#### 15.2.2。浮點字面值
浮點數只能用基數 10 表示。
分數:
```js
> 35.0
35
```
指數:`eN`表示`10 ** N`
```js
> 3e2
300
> 3e-2
0.03
> 0.3e2
30
```
#### 15.2.3。語法缺陷:整數字面值的屬性
訪問整數字面值的屬性會帶來陷阱:如果整數字面值后面緊跟一個點,則該點被解釋為小數點:
```js
7.toString(); // syntax error
```
有四種方法可以解決這個陷阱:
```js
7.0.toString()
(7).toString()
7..toString()
7 .toString() // space before dot
```
### 15.3。數字運算符
#### 15.3.1。二元算術運算符
```js
assert.equal(1 + 4, 5); // addition
assert.equal(6 - 3, 3); // subtraction
assert.equal(2 * 1.25, 2.5); // multiplication
assert.equal(6 / 4, 1.5); // division
assert.equal(6 % 4, 2); // remainder
assert.equal(2 ** 3, 8); // exponentiation
```
`%`是余數運算符(不是模運算符) - 其結果具有第一個操作數的符號:
```js
> 3 % 2
1
> -3 % 2
-1
```
#### 15.3.2。一元加法和相反數
```js
assert.equal(+(-3), -3); // unary plus
assert.equal(-(-3), 3); // unary negation
```
兩個運算符都將他們的操作數強制轉換為數字:
```js
> +'7'
7
> +'-12'
-12
> -'9'
-9
```
#### 15.3.3。自增(`++`)和自減(`--`)
自增運算符`++`存在前綴版本和后綴版本。在這兩個版本中,它破壞性地將其操作數加一。因此,其操作數必須是可以更改的存儲位置。自減運算符`--`的工作方式相同,但從其操作數中減一。接下來的兩個示例解釋了前綴和后綴版本之間的區別。
前綴`++`和前綴`--`:更改然后返回。
```js
let foo = 3;
assert.equal(++foo, 4);
assert.equal(foo, 4);
let bar = 3;
assert.equal(--bar, 2);
assert.equal(bar, 2);
```
后綴`++`和后綴`--`:返回然后更改。
```js
let foo = 3;
assert.equal(foo++, 3);
assert.equal(foo, 4);
let bar = 3;
assert.equal(bar--, 3);
assert.equal(bar, 2);
```
##### 15.3.3.1。操作數:不僅僅是變量
您還可以將這些運算符應用于屬性值:
```js
const obj = { a: 1 };
++obj.a;
assert.equal(obj.a, 2);
```
并且用于數組元素:
```js
const arr = [ 4 ];
arr[0]++;
assert.deepEqual(arr, [5]);
```
 **練習:數字運算符**
`exercises/numbers-math/is_odd_test.js`
### 15.4。轉換為數字
這些是將值轉換為數字的三種方法:
* `Number(value)`
* `+value`
* `parseFloat(value)`(避免;與其他兩個不同!)
建議:使用描述性`Number()`。
例子:
```js
assert.equal(Number(undefined), NaN);
assert.equal(Number(null), 0);
assert.equal(Number(false), 0);
assert.equal(Number(true), 1);
assert.equal(Number(123), 123);
assert.equal(Number(''), 0);
assert.equal(Number('123'), 123);
assert.equal(Number('xyz'), NaN);
```
可以配置如何將對象轉換為數字。例如,通過覆蓋`.valueOf()`:
```js
> Number({ valueOf() { return 123 } })
123
```
 **練習:轉換為數字**
`exercises/numbers-math/parse_number_test.js`
### 15.5。錯誤值
發生錯誤時返回兩個數字值:
* `NaN`
* `Infinity`
### 15.6。錯誤值:`NaN`
`NaN`是“非數字”的縮寫。具有諷刺意味的是,JavaScript 認為它是一個數字:
```js
> typeof NaN
'number'
```
什么時候返回`NaN`?
如果無法解析數字,則返回`NaN`:
```js
> Number('$$$')
NaN
> Number(undefined)
NaN
```
如果無法執行操作,則返回`NaN`:
```js
> Math.log(-1)
NaN
> Math.sqrt(-1)
NaN
```
如果操作數或參數是`NaN`(傳播錯誤),則返回`NaN`:
```js
> NaN - 3
NaN
> 7 ** NaN
NaN
```
#### 15.6.1。檢查`NaN`
`NaN`是唯一不嚴格等于自己的 JavaScript 值:
```js
const n = NaN;
assert.equal(n === n, false);
```
這些是檢查值`x`是否為`NaN`的幾種方法:
```js
const x = NaN;
assert.equal(Number.isNaN(x), true); // preferred
assert.equal(Object.is(x, NaN), true);
assert.equal(x !== x, true);
```
在最后一行,我們使用比較小技巧來檢測`NaN`。
#### 15.6.2。在數組中查找`NaN`
有些數組方法找不到`NaN`:
```js
> [NaN].indexOf(NaN)
-1
```
其他可以:
```js
> [NaN].includes(NaN)
true
> [NaN].findIndex(x => Number.isNaN(x))
0
> [NaN].find(x => Number.isNaN(x))
NaN
```
唉,沒有簡單的經驗法則,你必須檢查每個方法,它如何處理`NaN`。
### 15.7。錯誤值:`Infinity`
何時返回錯誤值`Infinity`?
如果數字太大,則返回無窮大:
```js
> Math.pow(2, 1023)
8.98846567431158e+307
> Math.pow(2, 1024)
Infinity
```
如果除以零,則返回無窮大:
```js
> 5 / 0
Infinity
> -5 / 0
-Infinity
```
#### 15.7.1。 `Infinity`作為默認值
`Infinity`大于所有其他數字(`NaN`除外),使其成為一個很好的默認值:
```js
function findMinimum(numbers) {
let min = Infinity;
for (const n of numbers) {
if (n < min) min = n;
}
return min;
}
assert.equal(findMinimum([5, -1, 2]), -1);
assert.equal(findMinimum([]), Infinity);
```
#### 15.7.2。檢查`Infinity`
這是檢查值`x`是否為`Infinity`的兩種常用方法:
```js
const x = Infinity;
assert.equal(x === Infinity, true);
assert.equal(Number.isFinite(x), false);
```
 **練習:比較數字**
`exercises/numbers-math/find_max_test.js`
### 15.8。數字的精確度:小心小數
在內部,JavaScript 浮點數用基數 2 表示(根據 IEEE 754 標準)。這意味著小數部分(基數 10)不能總是精確表示:
```js
> 0.1 + 0.2
0.30000000000000004
> 1.3 * 3
3.9000000000000004
> 1.4 * 100000000000000
139999999999999.98
```
因此,在 JavaScript 中執行算術時需要考慮舍入誤差。
繼續閱讀來解釋這種現象。
 **測驗:基本**
參見[測驗應用程序](ch_quizzes-exercises.html#quizzes)。
### 15.9。 (高級)
本章的所有其余部分都是高級的。
### 15.10。背景:浮點精度
在 JavaScript 中,使用數字進行計算并不總能產生精確的結果。例如:
```js
> 0.1 + 0.2
0.30000000000000004
```
要理解原因,我們需要探索 JavaScript 如何在內部表示浮點數。它使用三個整數來執行此操作,如表 5 中所述。
表 5:在內部,JavaScript 使用三個整數來表示浮點數。它們總共占用 64 位存儲空間(雙精度)。
| 成分 | 大小 | 整數范圍 |
| --- | --- | --- |
| 符號 | 1 位 | `[0,1]` |
| 小數 | 52 位 | `[0,2 ** 52 -1]` |
| 指數 | 11 位 | `[-1023,1024]` |
由這些整數表示的浮點數計算如下:
> `(-1) ** 符號 * 0b1.小數 * 2 ** 指數`
為了進一步討論,我們簡化了這種表示:
* 我們使用基數 10(十進制)代替基數 2(二進制),因為這是大多數人更熟悉的。
* *小數*是一個解釋為小數的自然數(一個點后的數字)。我們切換到*尾數*,這是一個被解釋為自身的整數。因此,指數的使用方式不同,但其基本作用不會改變。
* 由于尾數是一個整數(有自己的符號),我們不再需要單獨的符號了。
新表示的工作方式如下:
> `尾數 * 10 ** 指數`
讓我們試試幾個浮點數的表示。
* 對于整數`-123`,我們主要需要尾數:
```js
> -123 * (10 ** 0)
-123
```
* 對于數字`1.5`,我們想象尾數后面有一個點。我們使用負指數將該點向左移動一位:
```js
> 15 * (10 ** -1)
1.5
```
* 對于數字`0.25`,我們將點向右移動兩位數:
```js
> 25 * (10 ** -2)
0.25
```
具有負指數的表示也可以寫為分母中具有正指數的分數:
```js
> 15 * (10 ** -1) === 15 / 10
true
> 25 * (10 ** -2) === 25 / 100
true
```
這些分數有助于理解為什么我們的編碼無法表示數字:
* 可以表示`1/10`。它已經具有所需的格式:分母是 10 的冪。
* `1/2`可以表示為`5/10`。我們通過將分子和分母乘以 5,將分母中的 2 變為 10 的冪。
* `1/4`可以表示為`25/100`。通過將分子和分母乘以 25,我們將分母中的 4 變為 10 的冪。
* `1/3`無法表示。沒有辦法將分母變為 10 的冪。(10 的素數因子是 2 和 5。因此,任何只有這些素數因子的分母都可以通過使用足夠的二和五乘以分子和分母,來轉換為 10 的冪。如果分母有不同的素因子,那么我們無能為力。)
為了結束游覽,我們切換回基數 2:
* `0.5 = 1/2`可以用基數 2 表示,因為分母已經是 2 的冪。
* `0.25 = 1/4`可以用基數 2 表示,因為分母已經是 2 的冪。
* 無法表示`0.1 = 1/10`,因為分母無法轉換為 2 的冪。
* 無法表示`0.2 = 2/10`,因為分母無法轉換為 2 的冪。
現在我們可以看到為什么`0.1 + 0.2`不能產生精確的結果:在內部,兩個操作數都不能精確表示。
精確計算小數分數的唯一方法是通過內部切換到基數 10。對于許多編程語言,基數 2 是默認值,基數 10 是一個選項。例如,Java 具有類[`BigDecimal`](https://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html) ,Python 具有模塊 [`decimal`](https://docs.python.org/3/library/decimal.html)。JavaScript 暫時有計劃添加類似的東西:ECMAScript 提案“Decimal”目前在[階段 0](https://github.com/tc39/proposals/blob/master/stage-0-proposals.md)。
### 15.11。 JavaScript 中的整數
JavaScript 沒有特殊的整數類型。相反,它們只是沒有小數部分的正常(浮點)數字:
```js
> 1 === 1.0
true
> Number.isInteger(1.0)
true
```
在本節中,我們將介紹一些使用這些偽整數的工具。
#### 15.11.1。轉換為整數
將數字轉換為整數的推薦方法是使用`Math`對象的一種舍入方法(在[下一章](ch_math.html)中記錄):
* `Math.floor(n)`:返回`i ≤ n`的最大整數
```js
> Math.floor(2.1)
2
> Math.floor(2.9)
2
```
* `Math.ceil(n)`:返回`i ≥ n`的最小整數
```js
> Math.ceil(2.1)
3
> Math.ceil(2.9)
3
```
* `Math.round(n)`:返回“最接近”`n`的整數。0.5 向上舍入。例如:
```js
> Math.round(2.4)
2
> Math.round(2.5)
3
```
* `Math.trunc(n)`:刪除`n`具有的任何小數部分(在小數點之后),因此將其轉換為整數。
```js
> Math.trunc(2.1)
2
> Math.trunc(2.9)
2
```
表 6 顯示這些函數的各種輸入的結果。
表 6: 將數字轉換為整數的函數。 注意事情如何隨負數變化,因為“較大”總是意味著“接近正無窮大”。
| | `-2.9` | `-2.5` | `-2.1` | `2.1` | `2.5` | `2.9` |
| --- | --- | --- | --- | --- | --- | --- |
| `Math.floor` | `-3` | `-3` | `-3` | `2` | `2` | `2` |
| `Math.ceil` | `-2` | `-2` | `-2` | `3` | `3` | `3` |
| `Math.round` | `-3` | `-2` | `-2` | `2` | `3` | `3` |
| `Math.trunc` | `-2` | `-2` | `-2` | `2` | `2` | `2` |
#### 15.11.2。 JavaScript 中的整數范圍
這些是 JavaScript 中重要的整數范圍:
* **安全整數:**可以通過 JavaScript“安全地”表示(意味著什么后面會講更多)
* 精度:53 位帶符號
* 范圍:`(-2 ** 53 ~ 2 ** 53)`
* **數組索引**
* 精度:32 位,無符號
* 范圍:`[0, 2 ** 32 - 1)`(不包括最大長度)
* 類型數組有更大的 53 位范圍(安全和無符號)
* **按位操作數**(按位或,等等)
* 精度:32 位
* 無符號右移范圍(`>>>`):無符號,`[0, 2 ** 32)`
* 所有其他按位運算符的范圍:有符號,`[-2 ** 31, 2 ** 31)`
#### 15.11.3。安全整數
這是 JavaScript 中*安全*的整數范圍:
> `[-2 ** 53 - 1, 2 ** 53 - 1]`
如果一個整數是*安全*的,則它只由一個 JavaScript 數字表示。鑒于 JavaScript 數字被編碼為小數乘以二的指數次冪,也可以表示更高的整數,但它們之間存在間隙。
例如(18014398509481984 是`2 ** 54`):
```js
> 18014398509481984
18014398509481984
> 18014398509481985
18014398509481984
> 18014398509481986
18014398509481984
> 18014398509481987
18014398509481988
```
`Number`的以下屬性有助于確定整數是否安全:
```js
assert.equal(Number.MAX_SAFE_INTEGER, (2 ** 53) - 1);
assert.equal(Number.MIN_SAFE_INTEGER, -Number.MAX_SAFE_INTEGER);
assert.equal(Number.isSafeInteger(5), true);
assert.equal(Number.isSafeInteger('5'), false);
assert.equal(Number.isSafeInteger(5.1), false);
assert.equal(Number.isSafeInteger(Number.MAX_SAFE_INTEGER), true);
assert.equal(Number.isSafeInteger(Number.MAX_SAFE_INTEGER+1), false);
```
 **練習:檢測安全整數**
`exercises/numbers-math/is_safe_integer_test.js`
##### 15.11.3.1。安全的計算
讓我們看一下涉及不安全整數的計算。
以下結果不正確且不安全,即使它的兩個操作數都是安全的。
```js
> 9007199254740990 + 3
9007199254740992
```
以下結果是安全的,但不正確。第一個操作數是不安全的,第二個操作數是安全的。
```js
> 9007199254740995 - 10
9007199254740986
```
因此,當且僅當兩個操作數和結果都是安全的時,表達式`a op b`的結果才是正確的:
```js
isSafeInteger(a) && isSafeInteger(b) && isSafeInteger(a op b)
```
### 15.12。按位運算符
JavaScript 按位運算符的工作方式如下:
* 首先,操作數轉換為數字(64 位雙浮點數),然后轉換為 32 位整數。
* 然后執行按位操作。
* 最后,結果將轉換回雙精度并返回。
在內部,運算符使用以下整數范圍(輸入和輸出):
* 無符號右移運算符(`>>>`):32 位,范圍`[0, 2 ** 32)`
* 所有其他按位運算符:32 位包括符號,范圍`[-2 ** 31, 2 ** 31)`
如果我們以二進制表示法將它們顯示為無符號 32 位整數,則其中一些運算符的結果最容易理解。這就是`b32()`的作用(其實現將在后面顯示):
```js
assert.equal(
b32(-1),
'11111111111111111111111111111111');
assert.equal(
b32(1),
'00000000000000000000000000000001');
assert.equal(
b32(2 ** 31),
'10000000000000000000000000000000');
```
#### 15.12.1。二元按位運算符
表 7:二進制按位運算符
| 運算符 | 名稱 |
| --- | --- |
| `num1 & num2` | 按位和 |
| <code>num1 | num2</code> | 按位或 |
| `num1 ^ num2` | 按位異或 |
二元運算符(表 7 )組合其操作數的位來產生它們的結果:
```js
> (0b1010 & 0b11).toString(2).padStart(4, '0')
'0010'
> (0b1010 | 0b11).toString(2).padStart(4, '0')
'1011'
> (0b1010 ^ 0b11).toString(2).padStart(4, '0')
'1001'
```
#### 15.12.2。按位非
表 8 :按位非
| 運算符 | 名稱 |
| --- | --- |
| `~num` | 按位非,補碼 |
按位非運算符(表 8)反轉其操作數的每個二進制位:
```js
> b32(~0b100)
'11111111111111111111111111111011'
```
#### 15.12.3。移位運算符
表 9:移位運算符
| 運算符 | 名稱 |
| --- | --- |
| `num << count` | 左移 |
| `num >> count` | 有符號右移 |
| `num >>> count` | 無符號右移 |
移位運算符(表 9)向左或向右移動二進制位:
```js
> (0b10 << 1).toString(2)
'100'
```
`>>`保留最高位,`>>>`不保留:
```js
> b32(0b10000000000000000000000000000010 >> 1)
'11000000000000000000000000000001'
> b32(0b10000000000000000000000000000010 >>> 1)
'01000000000000000000000000000001'
```
#### 15.12.4。 `b32()`:以二進制表示法顯示 32 位整數
我們現在使用了`b32()`幾次。以下代碼是它的實現。
```js
/**
* Return a string representing n as a 32-bit unsigned integer,
* in binary notation.
*/
function b32(n) {
// >>> ensures highest bit isn’t interpreted as a sign
return (n >>> 0).toString(2).padStart(32, '0');
}
assert.equal(
b32(6),
'00000000000000000000000000000110');
```
`n >>> 0`表示我們將`n`零位向右移位。因此,原則上,`>>>`運算符不執行任何操作,但它仍然將`n`強制轉換為無符號的 32 位整數:
```js
> 12 >>> 0
12
> -12 >>> 0
4294967284
> (2**32 + 1) >>> 0
1
```
### 15.13。快速參考:數字
#### 15.13.1。轉換為數字
表 10 顯示如果通過`Number()`將各種值轉換為數字會發生什么。
表 10:將值轉換為數字
| `x` | `Number(x)` |
| --- | --- |
| `undefined` | `NaN` |
| `null` | `0` |
| 布爾值 | `false → 0`,`true → 1` |
| 數字 | `x`(無變化) |
| 字符串 | `'' → 0` |
| | 其他 → 解析的數字,忽略前導/尾隨空格 |
| 對象 | 可配置的(例如通過`.valueOf()`) |
#### 15.13.2。算術運算符
JavaScript 有以下算術運算符:
* 二元算術運算符(表 11)
* 前綴和后綴算術運算符(表 12)
表 11:二元算術運算符
| 運算符 | 名稱 | | 示例 |
| --- | --- | --- | --- |
| `n + m` | 加法 | ES1 | `3 + 4 → 7` |
| `n - m` | 減法 | ES1 | `9 - 1 → 8` |
| `n * m` | 乘法 | ES1 | `3 * 2.25 → 6.75` |
| `n / m` | 除法 | ES1 | `5.625 / 5 → 1.125` |
| `n % m` | 余數 | ES1 | `8 % 5 → 3` |
| | | | `-8 % 5 → -3` |
| `n ** m` | 冪 | ES2016 | `4 ** 2 → 16` |
表 12:前綴和后綴算術運算符
| 運算符 | 名稱 | | 示例 |
| --- | --- | --- | --- |
| `+n` | 一元加 | ES1 | `+(-7) → -7` |
| `-n` | 一元減 | ES1 | `-(-7) → 7` |
| `v++` | 自增 | ES1 | `let v=0; [v++, v] → [0, 1]` |
| `++v` | 自增 | ES1 | `let v=0; [++v, v] → [1, 1]` |
| `v--` | 自減 | ES1 | `let v=1; [v--, v] → [1, 0]` |
| `--v` | 自減 | ES1 | `let v=1; [--v, v] → [0, 0]` |
#### 15.13.3。按位運算符
JavaScript 具有以下按位運算符:
* 按位和,或,異或,非(表 13)
* 移位運算符(表 14)
按位運算符的操作數和結果:
* 無符號右移運算符(`>>>`):32 位,范圍`[0, 2 ** 32)`
* 所有其他按位運算符:32 位帶符號,范圍`[-2 ** 31, 2 ** 31)`
顯示二進制數的輔助函數`b32()`在[本章前面的章節](ch_numbers.html#b32)中顯示。
表 13:按位和,或,異或,非
| 運算符 | 名稱 | | 示例 |
| --- | --- | --- | --- |
| `i & j` | 按位和 | ES1 | `(0b1010 & 0b1100).toString(2) → '1000'` |
| <code>i | j</code> | 按位或 | ES1 | <code>(0b1010 | 0b1100).toString(2) → '1110'</code> |
| `i ^ j` | 按位異或 | ES1 | `(0b1010 ^ 0b0011).toString(2) → '1001'` |
| `~i` | 按位非 | ES1 | `~0b11111111111111111111111111111110 → 1` |
表 14:移位運算符
| 運算符 | 名稱 | | 示例 |
| --- | --- | --- | --- |
| `i << j` | 左移 | ES1 | `(0b1 << 1).toString(2) → '10'` |
| `i >> j` | 符號右移 | ES1 | `b32(0b10000000000000000000000000000010 >> 1)` |
| | | | `→ '11000000000000000000000000000001'` |
| `i >>> j` | 無符號右移 | ES1 | `b32(0b10000000000000000000000000000010 >>> 1)` |
| | | | `→ '01000000000000000000000000000001'` |
#### 15.13.4。數字的全局函數
JavaScript 具有以下四個全局函數:
* `isFinite()`
* `isNaN()`
* `parseFloat()`
* `parseInt()`
但是,最好使用`Number`的相應方法,這些方法具有較少的陷阱:`Number.isFinite()`,`Number.isNaN()`,`Number.parseFloat()`,`Number.parseInt()`。它們是與 ES6 一起引入的,將在下面討論。
#### 15.13.5。 `Number`的靜態屬性
* `.EPSILON: number` <sup>[ES6]</sup>
1 和下一個可表示的浮點數之間的差異。通常,[機器的 epsilon](https://en.wikipedia.org/wiki/Machine_epsilon) 為浮點運算中的舍入誤差提供上限。
* 大約為:`2.2204460492503130808472633361816 * 10 ** (-16)`
* `.MAX_SAFE_INTEGER: number` <sup>[ES6]</sup>
JavaScript 可以明確表示的最大整數(`2 ** 53 - 1`)。
* `.MAX_VALUE: number` <sup>[ES1]</sup>
最大的正有限 JavaScript 數。
* 大約為:`1.7976931348623157 * 10 ** 308`
* `.MIN_SAFE_INTEGER: number` <sup>[ES6]</sup>
JavaScript 可以明確表示的最小整數(`-2 ** 53 + 1`)。
* `.MIN_VALUE: number` <sup>[ES1]</sup>
最小的 JavaScript 正數。大約`5 * 10 ** -324`。
* `.NaN: number` <sup>[ES1]</sup>
與全局變量`NaN`相同。
* `.NEGATIVE_INFINITY: number` <sup>[ES1]</sup>
與`-Number.POSITIVE_INFINITY`相同。
* `.POSITIVE_INFINITY: number` <sup>[ES1]</sup>
與全局變量`Infinity`相同。
#### 15.13.6。 `Number`的靜態方法
* `.isFinite(num: number): boolean` <sup>[ES6]</sup>
如果`num`是實際數字(不是`Infinity`,`-Infinity`和`NaN`),則返回`true`。
```js
> Number.isFinite(Infinity)
false
> Number.isFinite(-Infinity)
false
> Number.isFinite(NaN)
false
> Number.isFinite(123)
true
```
* `.isInteger(num: number): boolean` <sup>[ES6]</sup>
如果`num`是一個數字并且沒有小數部分,則返回`true`。
```js
> Number.isInteger(-17)
true
> Number.isInteger(33)
true
> Number.isInteger(33.1)
false
> Number.isInteger('33')
false
> Number.isInteger(NaN)
false
> Number.isInteger(Infinity)
false
```
* `.isNaN(num: number): boolean` <sup>[ES6]</sup>
如果`num`是值`NaN`,則返回`true`:
```js
> Number.isNaN(NaN)
true
> Number.isNaN(123)
false
> Number.isNaN('abc')
false
```
* `.isSafeInteger(num: number): boolean` <sup>[ES6]</sup>
如果`num`是一個數字并且明確表示一個整數,則返回`true`。
* `.parseFloat(str: string): number` <sup>[ES6]</sup>
將其參數強制轉換為字符串并將其解析為浮點數。為了將字符串轉換為數字,`Number()`(忽略前導和尾隨空格)通常是比`Number.parseFloat()`更好的選擇(它忽略前導空格和非法尾隨字符并且可以隱藏問題)。
```js
> Number.parseFloat(' 123.4#')
123.4
> Number(' 123.4#')
NaN
```
* `.parseInt(str: string, radix=10): number` <sup>[ES6]</sup>
將其參數強制轉換為字符串并將其解析為整數,忽略前導空格和非法尾隨字符:
```js
> Number.parseInt(' 123#')
123
```
參數`radix`指定要解析的數字的基數:
```js
> Number.parseInt('101', 2)
5
> Number.parseInt('FF', 16)
255
```
不要使用此方法將數字轉換為整數:強制轉換為字符串是低效的。并且在第一個非數字之前停止,不是用于移除數字的小數的良好算法。這是一個出錯的例子:
```js
> Number.parseInt(1e21, 10) // wrong
1
```
最好使用`Math`的一個舍入函數將數字轉換為整數:
```js
> Math.trunc(1e21) // correct
1e+21
```
#### 15.13.7。 `Number.prototype`的方法
* `.toExponential(fractionDigits?: number): string` <sup>[ES3]</sup>
返回一個字符串,該字符串通過指數表示法表示數字。使用`fractionDigits`,您可以指定與指數相乘的數字的位數(默認值是根據需要顯示位數)。
示例:數字太小而無法通過`.toString()`獲得正指數。
```js
> 1234..toString()
'1234'
> 1234..toExponential()
'1.234e+3'
> 1234..toExponential(5)
'1.23400e+3'
```
示例:數字太小而無法通過`.toString()`得到負指數。
```js
> 0.003.toString()
'0.003'
> 0.003.toExponential()
'3e-3'
> 0.003.toExponential(4)
'3.0000e-3'
```
* `.toFixed(fractionDigits=0): string` <sup>[ES3]</sup>
返回數字的無指數表示,舍入為`fractionDigits`個數字。
```js
> 0.0000003.toString()
'3e-7'
> 0.0000003.toFixed(10)
'0.0000003000'
> 0.0000003.toFixed()
'0'
```
如果數字為`10 ** 21` 或更高,則`.toFixed()`使用指數:
```js
> (10 ** 21).toFixed()
'1e+21'
```
* `.toPrecision(precision?: number): string` <sup>[ES3]</sup>
像`.toString()`一樣工作,但在返回結果之前將尾數修剪為數字`precision`。如果缺少`precision`,則使用`.toString()`。
```js
> 1234..toPrecision(3) // requires exponential notation
'1.23e+3'
> 1234..toPrecision(4)
'1234'
> 1234..toPrecision(5)
'1234.0'
> 1.234.toPrecision(3)
'1.23'
```
* `.toString(radix=10): string` <sup>[ES1]</sup>
返回數字的字符串表示形式。
返回基數為 10 的結果:
```js
> 123.456.toString()
'123.456'
```
使用 10 以外的基數返回結果(通過`radix`指定):
```js
> 4..toString(2)
'100'
> 4.5.toString(2)
'100.1'
> 255..toString(16)
'ff'
> 255.66796875.toString(16)
'ff.ab'
> 1234567890..toString(36)
'kf12oi'
```
您可以使用`parseInt()`將整數結果轉換回數字:
```js
> parseInt('kf12oi', 36)
1234567890
```
#### 15.13.8。來源
* 維基百科
* [TypeScript 的內置類型](https://github.com/Microsoft/TypeScript/blob/master/lib/)
* [JavaScript 的 MDN 網絡文檔](https://developer.mozilla.org/en-US/docs/Web/JavaScript)
* [ECMAScript 語言規范](https://tc39.github.io/ecma262/)
 **測驗:高級**
參見[測驗應用程序](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.其余章節在哪里?