數字和字串

本章將介紹 JavaScript 中兩個最基本的資料型別:數字和字串。我們將介紹它們的底層表示,以及用於處理和執行計算的函式。

數字

在 JavaScript 中,數字採用雙精度 64 位二進位制格式 IEEE 754 實現(即,一個介於 ±2^−1022 和 ±2^+1023 之間的數字,或者大約 ±10^−308 到 ±10^+308 之間,數字精度為 53 位)。整數值可精確表示到 ±2^53 − 1。

除了能夠表示浮點數之外,數字型別還有三個符號值:Infinity-InfinityNaN(非數字)。

另請參閱 JavaScript 資料型別和結構,以瞭解 JavaScript 中其他基本型別的上下文。

您可以使用四種類型的數字字面量:十進位制、二進位制、八進位制和十六進位制。

十進位制數字

js
1234567890
42

十進位制字面量可以以零 (0) 開頭,後跟另一個十進位制數字,但如果前導 0 之後的所有數字都小於 8,則該數字被解釋為八進位制數字。這被認為是遺留語法,以 0 為字首的數字字面量,無論是解釋為八進位制還是十進位制,在嚴格模式下都會導致語法錯誤——因此,請改用 0o 字首。

js
0888 // 888 parsed as decimal
0777 // parsed as octal, 511 in decimal

二進位制數字

二進位制數字語法使用前導零,後跟小寫或大寫拉丁字母“B”(0b0B)。如果 0b 之後的數字不是 0 或 1,則會丟擲以下 SyntaxError:“Missing binary digits after 0b”。

js
0b10000000000000000000000000000000 // 2147483648
0b01111111100000000000000000000000 // 2139095040
0B00000000011111111111111111111111 // 8388607

八進位制數字

八進位制數字的標準語法是字首 0o。例如

js
0O755 // 493
0o644 // 420

八進位制數字也有一個遺留語法——透過在八進位制數字前加一個零:0644 === 420"\045" === "%"。如果 0 之後的數字超出 0 到 7 的範圍,則該數字將被解釋為十進位制數字。

js
const n = 0755; // 493
const m = 0644; // 420

嚴格模式禁止這種八進位制語法。

十六進位制數字

十六進位制數字語法使用前導零,後跟小寫或大寫拉丁字母“X”(0x0X)。如果 0x 之後的數字超出範圍(0123456789ABCDEF),則會丟擲以下 SyntaxError:“Identifier starts immediately after numeric literal”。

js
0xFFFFFFFFFFFFF // 4503599627370495
0xabcdef123456  // 188900967593046
0XA             // 10

冪運算

js
0e-5   // 0
0e+5   // 0
5e1    // 50
175e-2 // 1.75
1e3    // 1000
1e-3   // 0.001
1E3    // 1000

數字分隔符

對於上面顯示的所有字面量語法,可以在數字之間插入下劃線 (_) 以提高可讀性。

js
1_000_000_000_000
1_050.95
0b1010_0001_1000_0101
0o2_2_5_6
0xA0_B0_C0
1_000_000_000_000_000_000_000n

有關數字字面量的更多詳細資訊,請參閱詞法語法參考。

Number 物件

內建的 Number 物件具有數值常數的屬性,例如最大值、非數字和無窮大。您無法更改這些屬性的值,並且可以按如下方式使用它們

js
const biggestNum = Number.MAX_VALUE;
const smallestNum = Number.MIN_VALUE;
const infiniteNum = Number.POSITIVE_INFINITY;
const negInfiniteNum = Number.NEGATIVE_INFINITY;
const notANum = Number.NaN;

您始終如上所示引用預定義的 Number 物件的屬性,而不是您自己建立的 Number 物件的屬性。

下表總結了 Number 物件的屬性。

屬性 描述
Number.MAX_VALUE 最大可表示正數 (1.7976931348623157e+308)
Number.MIN_VALUE 最小可表示正數 (5e-324)
Number.NaN 特殊“非數字”值
Number.NEGATIVE_INFINITY 特殊負無窮大值;溢位時返回
Number.POSITIVE_INFINITY 特殊正無窮大值;溢位時返回
Number.EPSILON 1 與大於 1 且可以表示為 Number 的最小數值之間的差值 (2.220446049250313e-16)
Number.MIN_SAFE_INTEGER JavaScript 中的最小安全整數(−2^53 + 1,或 −9007199254740991
Number.MAX_SAFE_INTEGER JavaScript 中的最大安全整數(+2^53 − 1,或 +9007199254740991
方法 描述
Number.parseFloat() 解析字串引數並返回浮點數。與全域性 parseFloat() 函式相同。
Number.parseInt() 解析字串引數並返回指定基數或底數的整數。與全域性 parseInt() 函式相同。
Number.isFinite() 確定傳入的值是否為有限數。
Number.isInteger() 確定傳入的值是否為整數。
Number.isNaN() 確定傳入的值是否為 NaN。比原始全域性 isNaN() 更健壯的版本。
Number.isSafeInteger() 確定提供的值是否為安全整數

Number 原型提供了以各種格式從 Number 物件檢索資訊的方法。下表總結了 Number.prototype 的方法。

方法 描述
toExponential() 返回一個以指數表示法表示數字的字串。
toFixed() 返回一個以定點表示法表示數字的字串。
toPrecision() 返回一個以定點表示法表示數字到指定精度的字串。

Math 物件

內建的 Math 物件具有數學常量和函式的屬性和方法。例如,Math 物件的 PI 屬性具有 pi 的值(3.141…),您將在應用程式中如下使用

js
Math.PI;

同樣,標準數學函式是 Math 的方法。這些包括三角函式、對數函式、指數函式和其他函式。例如,如果您想使用三角函式正弦,您將編寫

js
Math.sin(1.56);

請注意,Math 的所有三角方法都採用弧度作為引數。

下表總結了 Math 物件的方法。

Math 的方法
方法 描述
abs() 絕對值
sin()cos()tan() 標準三角函式;引數以弧度表示。
asin()acos()atan()atan2() 反三角函式;返回弧度值。
sinh()cosh()tanh() 雙曲函式;引數以雙曲角表示。
asinh()acosh()atanh() 反雙曲函式;返回雙曲角值。

pow()exp()expm1()log()log10()log1p()log2()

指數和對數函式。
floor()ceil() 返回小於/大於或等於引數的最大/最小整數。
min()max() 返回以逗號分隔的數字列表作為引數的最小值或最大值(分別)。
random() 返回 0 到 1 之間的隨機數。
round()fround()trunc() 舍入和截斷函式。
sqrt()cbrt()hypot() 平方根、立方根、平方和引數的平方根。
sign() 數字的符號,指示數字是正數、負數還是零。
clz32(),
imul()
32 位二進位制表示中前導零的位數。
兩個引數的 C 樣式的 32 位乘法結果。

與許多其他物件不同,您永遠不會建立自己的 Math 物件。您始終使用內建的 Math 物件。

BigInts

數字值的一個缺點是它們只有 64 位。實際上,由於使用 IEEE 754 編碼,它們無法準確表示任何大於 Number.MAX_SAFE_INTEGER(即 253 - 1)的整數。為了解決編碼二進位制資料以及與其他提供寬整數(如 i64(64 位整數)和 i128(128 位整數))的語言進行互操作的需求,JavaScript 還提供了另一種資料型別來表示任意大整數BigInt

BigInt 可以定義為字尾為 n 的整數文字

js
const b1 = 123n;
// Can be arbitrarily large.
const b2 = -1234567890987654321n;

BigInt 也可以使用 BigInt 建構函式從數字值或字串值構造。

js
const b1 = BigInt(123);
// Using a string prevents loss of precision, since long number
// literals don't represent what they seem like.
const b2 = BigInt("-1234567890987654321");

從概念上講,BigInt 只是一個任意長的位序列,它編碼一個整數。您可以安全地執行任何算術運算而不會丟失精度或溢位/下溢。

js
const integer = 12 ** 34; // 4.9222352429520264e+36; only has limited precision
const bigint = 12n ** 34n; // 4922235242952026704037113243122008064n

與數字相比,BigInt 值在表示大整數時具有更高的精度;但是,它們不能表示浮點數。例如,除法會四捨五入到零

js
const bigintDiv = 5n / 2n; // 2n, because there's no 2.5 in BigInt

Math 函式不能用於 BigInt 值;它們只適用於數字。

選擇 BigInt 還是數字取決於您的用例和輸入範圍。數字的精度應該能夠滿足大多數日常任務,而 BigInt 最適合處理二進位制資料。

有關您可以使用 BigInt 值執行的操作的更多資訊,請閱讀表示式和運算子部分,或BigInt 參考

字串

JavaScript 的 String 型別用於表示文字資料。它是一組 16 位無符號整數值(UTF-16 程式碼單元)的“元素”。字串中的每個元素都佔據字串中的一個位置。第一個元素位於索引 0,下一個位於索引 1,依此類推。字串的長度是其中元素的數量。您可以使用字串字面量或字串物件建立字串。

字串字面量

您可以使用單引號或雙引號在原始碼中宣告字串

js
'foo'
"bar"

在字串字面量中,大多數字符都可以按字面量輸入。唯一的例外是反斜槓 (\,它開始一個轉義序列)、用於包圍字串的引號字元(它終止字串),以及換行符(如果前面沒有反斜槓,則會導致語法錯誤)。

可以使用轉義序列建立更高階的字串

十六進位制轉義序列

\x 後面的數字被解釋為十六進位制數字。

js
"\xA9" // "©"

Unicode 轉義序列

Unicode 轉義序列要求 \u 後至少有四個十六進位制數字。

js
"\u00A9" // "©"

Unicode 程式碼點轉義

使用 Unicode 程式碼點轉義,可以使用十六進位制數字轉義任何字元,從而可以使用高達 0x10FFFF 的 Unicode 程式碼點。使用四位 Unicode 轉義通常需要單獨編寫代理對以實現相同的結果。

另請參閱 String.fromCodePoint()String.prototype.codePointAt()

js
"\u{2F804}"

// the same with simple Unicode escapes
"\uD87E\uDC04"

String 物件

您可以直接在字串值上呼叫方法

js
console.log("hello".toUpperCase()); // HELLO

String 值上提供了以下方法

處理字串時,還有兩個物件為字串操作提供重要功能:RegExpIntl。它們分別在正則表示式國際化中介紹。

模板字面量

模板字面量是允許嵌入表示式的字串字面量。您可以使用它們的多行字串和字串插值功能。

模板字面量由反引號(重音符)字元 (`) 包圍,而不是雙引號或單引號。模板字面量可以包含佔位符。這些由美元符號和花括號 (${expression}) 表示。

多行

原始碼中插入的任何換行符都是模板字面量的一部分。使用普通字串,您必須使用以下語法來獲取多行字串

js
console.log(
  "string text line 1\n\
string text line 2",
);
// "string text line 1
// string text line 2"

為了透過多行字串獲得相同的效果,您現在可以編寫

js
console.log(`string text line 1
string text line 2`);
// "string text line 1
// string text line 2"

嵌入式表示式

為了在普通字串中嵌入表示式,您將使用以下語法

js
const five = 5;
const ten = 10;
console.log(
  "Fifteen is " + (five + ten) + " and not " + (2 * five + ten) + ".",
);
// "Fifteen is 15 and not 20."

現在,使用模板字面量,您可以利用語法糖,使此類替換更具可讀性

js
const five = 5;
const ten = 10;
console.log(`Fifteen is ${five + ten} and not ${2 * five + ten}.`);
// "Fifteen is 15 and not 20."

有關更多資訊,請閱讀 JavaScript 參考中的模板字面量