Javascript 數(shù)據(jù)類型

2023-02-17 10:37 更新

JavaScript 中的值都具有特定的類型。例如,字符串或數(shù)字。

在 JavaScript 中有 8 種基本的數(shù)據(jù)類型(譯注:7 種原始類型和 1 種引用類型)。在這里,我們將對它們進(jìn)行大體的介紹,在下一章中,我們將詳細(xì)討論它們。

我們可以將任何類型的值存入變量。例如,一個(gè)變量可以在前一刻是個(gè)字符串,下一刻就存儲(chǔ)一個(gè)數(shù)字:

// 沒有錯(cuò)誤
let message = "hello";
message = 123456;

允許這種操作的編程語言,例如 JavaScript,被稱為“動(dòng)態(tài)類型”(dynamically typed)的編程語言,意思是雖然編程語言中有不同的數(shù)據(jù)類型,但是你定義的變量并不會(huì)在定義后,被限制為某一數(shù)據(jù)類型。

Number 類型

let n = 123;
n = 12.345;

number 類型代表整數(shù)和浮點(diǎn)數(shù)。

數(shù)字可以有很多操作,比如,乘法 *、除法 /、加法 +、減法 - 等等。

除了常規(guī)的數(shù)字,還包括所謂的“特殊數(shù)值(“special numeric values”)”也屬于這種類型:Infinity、-Infinity 和 NaN

  • ?Infinity ?代表數(shù)學(xué)概念中的 無窮大 ∞。是一個(gè)比任何數(shù)字都大的特殊值。
  • 我們可以通過除以 0 來得到它:

    alert( 1 / 0 ); // Infinity
    

    或者在代碼中直接使用它:

    alert( Infinity ); // Infinity
    
  • ?NaN ?代表一個(gè)計(jì)算錯(cuò)誤。它是一個(gè)不正確的或者一個(gè)未定義的數(shù)學(xué)操作所得到的結(jié)果,比如:
  • alert( "not a number" / 2 ); // NaN,這樣的除法是錯(cuò)誤的
    

    NaN 是粘性的。任何對 NaN 的進(jìn)一步數(shù)學(xué)運(yùn)算都會(huì)返回 NaN

    alert( NaN + 1 ); // NaN
    alert( 3 * NaN ); // NaN
    alert( "not a number" / 2 - 1 ); // NaN

    所以,如果在數(shù)學(xué)表達(dá)式中有一個(gè) NaN,會(huì)被傳播到最終結(jié)果(只有一個(gè)例外:NaN ** 0 結(jié)果為 1)。

數(shù)學(xué)運(yùn)算是安全的

在 JavaScript 中做數(shù)學(xué)運(yùn)算是安全的。我們可以做任何事:除以 0,將非數(shù)字字符串視為數(shù)字,等等。

腳本永遠(yuǎn)不會(huì)因?yàn)橐粋€(gè)致命的錯(cuò)誤(“死亡”)而停止。最壞的情況下,我們會(huì)得到 ?NaN ?的結(jié)果。

特殊的數(shù)值屬于 “number” 類型。當(dāng)然,對“特殊的數(shù)值”這個(gè)詞的一般認(rèn)識(shí)是,它們并不是數(shù)字。

我們將在 數(shù)字類型 一節(jié)中學(xué)習(xí)數(shù)字的更多細(xì)節(jié)。

BigInt 類型

在 JavaScript 中,“number” 類型無法安全地表示大于 (253-1)(即 9007199254740991),或小于 -(253-1) 的整數(shù)。

更準(zhǔn)確的說,“number” 類型可以存儲(chǔ)更大的整數(shù)(最多 1.7976931348623157 * 10308),但超出安全整數(shù)范圍 ±(253-1) 會(huì)出現(xiàn)精度問題,因?yàn)椴⒎撬袛?shù)字都適合固定的 64 位存儲(chǔ)。因此,可能存儲(chǔ)的是“近似值”。

例如,這兩個(gè)數(shù)字(正好超出了安全整數(shù)范圍)是相同的:

console.log(9007199254740991 + 1); // 9007199254740992
console.log(9007199254740991 + 2); // 9007199254740992

也就是說,所有大于 (253-1) 的奇數(shù)都不能用 “number” 類型存儲(chǔ)。

在大多數(shù)情況下,±(253-1) 范圍就足夠了,但有時(shí)候我們需要整個(gè)范圍非常大的整數(shù),例如用于密碼學(xué)或微秒精度的時(shí)間戳。

BigInt 類型是最近被添加到 JavaScript 語言中的,用于表示任意長度的整數(shù)。

可以通過將 n 附加到整數(shù)字段的末尾來創(chuàng)建 BigInt 值。

// 尾部的 "n" 表示這是一個(gè) BigInt 類型
const bigInt = 1234567890123456789012345678901234567890n;

由于很少需要 BigInt 類型的數(shù)字,我們在這沒有對其進(jìn)行講解,我們在單獨(dú)的章節(jié) BigInt 中專門對其進(jìn)行了介紹。當(dāng)你需要使用那樣的大數(shù)字的時(shí)候,可以去閱讀該章節(jié)。

兼容性問題

目前 Firefox/Chrome/Edge/Safari 已經(jīng)支持 BigInt 了,但 IE 還沒有。

你可以查看 MDN BigInt 兼容性表 以了解哪些版本的瀏覽器已經(jīng)支持 BigInt 了。

String 類型

JavaScript 中的字符串必須被括在引號里。

let str = "Hello";
let str2 = 'Single quotes are ok too';
let phrase = `can embed another ${str}`;

在 JavaScript 中,有三種包含字符串的方式。

  1. 雙引號:?"Hello"?.
  2. 單引號:?'Hello'?.
  3. 反引號:?`Hello`?.

雙引號和單引號都是“簡單”引用,在 JavaScript 中兩者幾乎沒有什么差別。

反引號是 功能擴(kuò)展 引號。它們允許我們通過將變量和表達(dá)式包裝在 ${…} 中,來將它們嵌入到字符串中。例如:

let name = "John";

// 嵌入一個(gè)變量
alert( `Hello, ${name}!` ); // Hello, John!

// 嵌入一個(gè)表達(dá)式
alert( `the result is ${1 + 2}` ); // the result is 3

${…} 內(nèi)的表達(dá)式會(huì)被計(jì)算,計(jì)算結(jié)果會(huì)成為字符串的一部分??梢栽?nbsp;${…} 內(nèi)放置任何東西:諸如名為 name 的變量,或者諸如 1 + 2 的算數(shù)表達(dá)式,或者其他一些更復(fù)雜的。

需要注意的是,這僅僅在反引號內(nèi)有效,其他引號不允許這種嵌入。

alert( "the result is ${1 + 2}" ); // the result is ${1 + 2}(使用雙引號則不會(huì)計(jì)算 ${…} 中的內(nèi)容)

我們會(huì)在 字符串 一節(jié)中學(xué)習(xí)字符串的更多細(xì)節(jié)。

JavaScript 中沒有 character 類型。

在一些語言中,單個(gè)字符有一個(gè)特殊的 “character” 類型,在 C 語言和 Java 語言中被稱為 “char”。

在 JavaScript 中沒有這種類型。只有一種 ?string ?類型,一個(gè)字符串可以包含零個(gè)(為空)、一個(gè)或多個(gè)字符。

Boolean 類型(邏輯類型)

boolean 類型僅包含兩個(gè)值:true 和 false。

這種類型通常用于存儲(chǔ)表示 yes 或 no 的值:true 意味著 “yes,正確”,false 意味著 “no,不正確”。

比如:

let nameFieldChecked = true; // yes, name field is checked
let ageFieldChecked = false; // no, age field is not checked

布爾值也可作為比較的結(jié)果:

let isGreater = 4 > 1;

alert( isGreater ); // true(比較的結(jié)果是 "yes")

更詳細(xì)的內(nèi)容將會(huì)在 邏輯運(yùn)算符 一節(jié)中介紹。

null 值

特殊的 null 值不屬于上述任何一種類型。

它構(gòu)成了一個(gè)獨(dú)立的類型,只包含 null 值:

let age = null;

相比較于其他編程語言,JavaScript 中的 null 不是一個(gè)“對不存在的 object 的引用”或者 “null 指針”。

JavaScript 中的 null 僅僅是一個(gè)代表“無”、“空”或“值未知”的特殊值。

上面的代碼表示 age 是未知的。

undefined 值

特殊值 undefined 和 null 一樣自成類型。

undefined 的含義是 未被賦值。

如果一個(gè)變量已被聲明,但未被賦值,那么它的值就是 undefined

let age;

alert(age); // 彈出 "undefined"

從技術(shù)上講,可以顯式地將 undefined 賦值給變量:

let age = 100;

// 將值修改為 undefined
age = undefined;

alert(age); // "undefined"

……但是不建議這樣做。通常,使用 null 將一個(gè)“空”或者“未知”的值寫入變量中,而 undefined 則保留作為未進(jìn)行初始化的事物的默認(rèn)初始值。

Object 類型和 Symbol 類型

object 類型是一個(gè)特殊的類型。

其他所有的數(shù)據(jù)類型都被稱為“原始類型”,因?yàn)樗鼈兊闹抵话粋€(gè)單獨(dú)的內(nèi)容(字符串、數(shù)字或者其他)。相反,object 則用于儲(chǔ)存數(shù)據(jù)集合和更復(fù)雜的實(shí)體。

因?yàn)樗浅V匾?,所以我們對其進(jìn)行單獨(dú)講解。在充分學(xué)習(xí)了原始類型后,我們將會(huì)在 對象 一章中介紹 object

symbol 類型用于創(chuàng)建對象的唯一標(biāo)識(shí)符。我們在這里提到 symbol 類型是為了完整性,但我們要在學(xué)完 object 類型后再學(xué)習(xí)它。

typeof 運(yùn)算符

typeof 運(yùn)算符返回參數(shù)的類型。當(dāng)我們想要分別處理不同類型值的時(shí)候,或者想快速進(jìn)行數(shù)據(jù)類型檢驗(yàn)時(shí),非常有用。

對 typeof x 的調(diào)用會(huì)以字符串的形式返回?cái)?shù)據(jù)類型:

typeof undefined // "undefined"

typeof 0 // "number"

typeof 10n // "bigint"

typeof true // "boolean"

typeof "foo" // "string"

typeof Symbol("id") // "symbol"

typeof Math // "object"  (1)

typeof null // "object"  (2)

typeof alert // "function"  (3)

最后三行可能需要額外的說明:

  1. ?Math ?是一個(gè)提供數(shù)學(xué)運(yùn)算的內(nèi)建 ?object?。我們會(huì)在 數(shù)字類型 一節(jié)中學(xué)習(xí)它。此處僅作為一個(gè) ?object ?的示例。
  2. ?typeof null? 的結(jié)果為 ?"object"?。這是官方承認(rèn)的 ?typeof ?的錯(cuò)誤,這個(gè)問題來自于 JavaScript 語言的早期階段,并為了兼容性而保留了下來。?null ?絕對不是一個(gè) ?object?。?null ?有自己的類型,它是一個(gè)特殊值。?typeof ?的行為在這里是錯(cuò)誤的。
  3. ?typeof alert? 的結(jié)果是 ?"function"?,因?yàn)?nbsp;?alert ?在 JavaScript 語言中是一個(gè)函數(shù)。我們會(huì)在下一章學(xué)習(xí)函數(shù),那時(shí)我們會(huì)了解到,在 JavaScript 語言中沒有一個(gè)特別的 “function” 類型。函數(shù)隸屬于 ?object ?類型。但是 ?typeof ?會(huì)對函數(shù)區(qū)分對待,并返回 ?"function"?。這也是來自于 JavaScript 語言早期的問題。從技術(shù)上講,這種行為是不正確的,但在實(shí)際編程中卻非常方便。

?typeof(x)? 語法

你可能還會(huì)遇到另一種語法:typeof(x)。它與 typeof x 相同。

簡單點(diǎn)說:typeof 是一個(gè)操作符,不是一個(gè)函數(shù)。這里的括號不是 typeof 的一部分。它是數(shù)學(xué)運(yùn)算分組的括號。

通常,這樣的括號里包含的是一個(gè)數(shù)學(xué)表達(dá)式,例如 (2 + 2),但這里它只包含一個(gè)參數(shù) (x)。從語法上講,它們允許在 typeof 運(yùn)算符和其參數(shù)之間不打空格,有些人喜歡這樣的風(fēng)格。

有些人更喜歡用 typeof(x),盡管 typeof x 語法更為常見。

總結(jié)

JavaScript 中有八種基本的數(shù)據(jù)類型(譯注:前七種為基本數(shù)據(jù)類型,也稱為原始數(shù)據(jù)類型,而 object 為復(fù)雜數(shù)據(jù)類型)。

  • 七種原始數(shù)據(jù)類型:
    • ?number ?用于任何類型的數(shù)字:整數(shù)或浮點(diǎn)數(shù),在 ?±(253-1)? 范圍內(nèi)的整數(shù)。
    • ?bigint ?用于任意長度的整數(shù)。
    • ?string ?用于字符串:一個(gè)字符串可以包含 0 個(gè)或多個(gè)字符,所以沒有單獨(dú)的單字符類型。
    • ?boolean ?用于 ?true ?和 ?false?。
    • ?null ?用于未知的值 —— 只有一個(gè) ?null ?值的獨(dú)立類型。
    • ?undefined ?用于未定義的值 —— 只有一個(gè) ?undefined ?值的獨(dú)立類型。
    • ?symbol ?用于唯一的標(biāo)識(shí)符。
  • 以及一種非原始數(shù)據(jù)類型:
    • ?object ?用于更復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。

我們可以通過 typeof 運(yùn)算符查看存儲(chǔ)在變量中的數(shù)據(jù)類型。

  • 通常用作 ?typeof x?,但 ?typeof(x)? 也可行。
  • 以字符串的形式返回類型名稱,例如 ?"string"?。
  • ?typeof null? 會(huì)返回 ?"object"? —— 這是 JavaScript 編程語言的一個(gè)錯(cuò)誤,實(shí)際上它并不是一個(gè) ?object?。

在接下來的章節(jié)中,我們將重點(diǎn)介紹原始類型值,當(dāng)你掌握了原始數(shù)據(jù)類型后,我們將繼續(xù)學(xué)習(xí) object。

任務(wù)


字符串的反引號

重要程度: 5

下面的腳本會(huì)輸出什么?

let name = "Ilya";

alert( `hello ${1}` ); // ?

alert( `hello ${"name"}` ); // ?

alert( `hello ${name}` ); // ?

解決方案

反引號將包裝在 ?${...}? 中的表達(dá)式嵌入到了字符串。

let name = "Ilya";

// 表達(dá)式為數(shù)字 1
alert( `hello ${1}` ); // hello 1

// 表達(dá)式是一個(gè)字符串 "name"
alert( `hello ${"name"}` ); // hello name

// 表達(dá)式是一個(gè)變量,嵌入進(jìn)去了。
alert( `hello ${name}` ); // hello Ilya


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號