JavaScript 中的值都具有特定的類型。例如,字符串或數字。
在 JavaScript 中有 8 種基本的數據類型(譯注:7 種原始類型和 1 種引用類型)。在這裏,我們將對它們進行大體的介紹,在下壹章中,我們將詳細討論它們。
我們可以將任何類型的值存入變量。例如,壹個變量可以在前壹刻是個字符串,下壹刻就存儲壹個數字:
// 沒有錯誤 let message = "hello"; message = 123456;
允許這種操作的編程語言,例如 JavaScript,被稱爲“動態類型”(dynamically typed)的編程語言,意思是雖然編程語言中有不同的數據類型,但是妳定義的變量並不會在定義後,被限制爲某壹數據類型。
let n = 123; n = 12.345;
number 類型代表整數和浮點數。
數字可以有很多操作,比如,乘法 *
、除法 /
、加法 +
、減法 -
等等。
除了常規的數字,還包括所謂的“特殊數值(“special numeric values”)”也屬于這種類型:Infinity
、-Infinity
和 NaN
。
Infinity
代表數學概念中的 無窮大 ∞。是壹個比任何數字都大的特殊值。
我們可以通過除以 0 來得到它:
alert( 1 / 0 ); // Infinity
或者在代碼中直接使用它:
alert( Infinity ); // Infinity
NaN
代表壹個計算錯誤。它是壹個不正確的或者壹個未定義的數學操作所得到的結果,比如:
alert( "not a number" / 2 ); // NaN,這樣的除法是錯誤的
NaN
是粘性的。任何對 NaN
的進壹步數學運算都會返回 NaN
:
alert( NaN + 1 ); // NaN alert( 3 * NaN ); // NaN alert( "not a number" / 2 - 1 ); // NaN
所以,如果在數學表達式中有壹個 NaN
,會被傳播到最終結果(只有壹個例外:NaN ** 0
結果爲 1
)。
數學運算是安全的
在 JavaScript 中做數學運算是安全的。我們可以做任何事:除以 0,將非數字字符串視爲數字,等等。
腳本永遠不會因爲壹個致命的錯誤(“死亡”)而停止。最壞的情況下,我們會得到 NaN
的結果。
特殊的數值屬于 “number” 類型。當然,對“特殊的數值”這個詞的壹般認識是,它們並不是數字。
我們將在 數字類型 壹節中學習數字的更多細節。
在 JavaScript 中,“number” 類型無法安全地表示大于 (253-1)
(即 9007199254740991
),或小于 -(253-1)
的整數。
更准確的說,“number” 類型可以存儲更大的整數(最多 1.7976931348623157 * 10308
),但超出安全整數範圍 ±(253-1)
會出現精度問題,因爲並非所有數字都適合固定的 64 位存儲。因此,可能存儲的是“近似值”。
例如,這兩個數字(正好超出了安全整數範圍)是相同的:
console.log(9007199254740991 + 1); // 9007199254740992 console.log(9007199254740991 + 2); // 9007199254740992
也就是說,所有大于 (253-1)
的奇數都不能用 “number” 類型存儲。
在大多數情況下,±(253-1)
範圍就足夠了,但有時候我們需要整個範圍非常大的整數,例如用于密碼學或微秒精度的時間戳。
BigInt
類型是最近被添加到 JavaScript 語言中的,用于表示任意長度的整數。
可以通過將 n
附加到整數字段的末尾來創建 BigInt
值。
// 尾部的 "n" 表示這是壹個 BigInt 類型 const bigInt = 1234567890123456789012345678901234567890n;
由于很少需要 BigInt
類型的數字,我們在這沒有對其進行講解,我們在單獨的章節 BigInt 中專門對其進行了介紹。當妳需要使用那樣的大數字的時候,可以去閱讀該章節。
兼容性問題
目前 Firefox/Chrome/Edge/Safari 已經支持 BigInt
了,但 IE 還沒有。
妳可以查看 MDN BigInt 兼容性表 以了解哪些版本的浏覽器已經支持 BigInt 了。
JavaScript 中的字符串必須被括在引號裏。
let str = "Hello"; let str2 = 'Single quotes are ok too'; let phrase = `can embed another ${str}`;
在 JavaScript 中,有三種包含字符串的方式。
雙引號:"Hello"
.
單引號:'Hello'
.
反引號:`Hello`
.
雙引號和單引號都是“簡單”引用,在 JavaScript 中兩者幾乎沒有什麽差別。
反引號是 功能擴展 引號。它們允許我們通過將變量和表達式包裝在 ${…}
中,來將它們嵌入到字符串中。例如:
let name = "John"; // 嵌入壹個變量 alert( `Hello, ${name}!` ); // Hello, John! // 嵌入壹個表達式 alert( `the result is ${1 + 2}` ); // the result is 3
${…}
內的表達式會被計算,計算結果會成爲字符串的壹部分。可以在 ${…}
內放置任何東西:諸如名爲 name
的變量,或者諸如 1 + 2
的算數表達式,或者其他壹些更複雜的。
需要注意的是,這僅僅在反引號內有效,其他引號不允許這種嵌入。
alert( "the result is ${1 + 2}" ); // the result is ${1 + 2}(使用雙引號則不會計算 ${…} 中的內容)
我們會在 字符串 壹節中學習字符串的更多細節。
JavaScript 中沒有 character 類型。
在壹些語言中,單個字符有壹個特殊的 “character” 類型,在 C 語言和 Java 語言中被稱爲 “char”。
在 JavaScript 中沒有這種類型。只有壹種 string
類型,壹個字符串可以包含零個(爲空)、壹個或多個字符。
boolean 類型僅包含兩個值:true
和 false
。
這種類型通常用于存儲表示 yes 或 no 的值:true
意味著 “yes,正確”,false
意味著 “no,不正確”。
比如:
let nameFieldChecked = true; // yes, name field is checked let ageFieldChecked = false; // no, age field is not checked
布爾值也可作爲比較的結果:
let isGreater = 4 > 1; alert( isGreater ); // true(比較的結果是 "yes")
更詳細的內容將會在 邏輯運算符 壹節中介紹。
特殊的 null
值不屬于上述任何壹種類型。
它構成了壹個獨立的類型,只包含 null
值:
let age = null;
相比較于其他編程語言,JavaScript 中的 null
不是壹個“對不存在的 object
的引用”或者 “null 指針”。
JavaScript 中的 null
僅僅是壹個代表“無”、“空”或“值未知”的特殊值。
上面的代碼表示 age
是未知的。
特殊值 undefined
和 null
壹樣自成類型。
undefined
的含義是 未被賦值
。
如果壹個變量已被聲明,但未被賦值,那麽它的值就是 undefined
:
let age; alert(age); // 彈出 "undefined"
從技術上講,可以顯式地將 undefined
賦值給變量:
let age = 100; // 將值修改爲 undefined age = undefined; alert(age); // "undefined"
……但是不建議這樣做。通常,使用 null
將壹個“空”或者“未知”的值寫入變量中,而 undefined
則保留作爲未進行初始化的事物的默認初始值。
object
類型是壹個特殊的類型。
其他所有的數據類型都被稱爲“原始類型”,因爲它們的值只包含壹個單獨的內容(字符串、數字或者其他)。相反,object
則用于儲存數據集合和更複雜的實體。
因爲它非常重要,所以我們對其進行單獨講解。在充分學習了原始類型後,我們將會在 對象 壹章中介紹 object
。
symbol
類型用于創建對象的唯壹標識符。我們在這裏提到 symbol
類型是爲了完整性,但我們要在學完 object
類型後再學習它。
typeof
運算符返回參數的類型。當我們想要分別處理不同類型值的時候,或者想快速進行數據類型檢驗時,非常有用。
對 typeof x
的調用會以字符串的形式返回數據類型:
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)
最後三行可能需要額外的說明:
Math
是壹個提供數學運算的內建 object
。我們會在 數字類型 壹節中學習它。此處僅作爲壹個 object
的示例。
typeof null
的結果爲 "object"
。這是官方承認的 typeof
的錯誤,這個問題來自于 JavaScript 語言的早期階段,並爲了兼容性而保留了下來。null
絕對不是壹個 object
。null
有自己的類型,它是壹個特殊值。typeof
的行爲在這裏是錯誤的。
typeof alert
的結果是 "function"
,因爲 alert
在 JavaScript 語言中是壹個函數。我們會在下壹章學習函數,那時我們會了解到,在 JavaScript 語言中沒有壹個特別的 “function” 類型。函數隸屬于 object
類型。但是 typeof
會對函數區分對待,並返回 "function"
。這也是來自于 JavaScript 語言早期的問題。從技術上講,這種行爲是不正確的,但在實際編程中卻非常方便。
typeof(x)
語法
妳可能還會遇到另壹種語法:typeof(x)
。它與 typeof x
相同。
簡單點說:typeof
是壹個操作符,不是壹個函數。這裏的括號不是 typeof
的壹部分。它是數學運算分組的括號。
通常,這樣的括號裏包含的是壹個數學表達式,例如 (2 + 2)
,但這裏它只包含壹個參數 (x)
。從語法上講,它們允許在 typeof
運算符和其參數之間不打空格,有些人喜歡這樣的風格。
有些人更喜歡用 typeof(x)
,盡管 typeof x
語法更爲常見。
JavaScript 中有八種基本的數據類型。
七種原始數據類型(基本數據類型):
number
用于任何類型的數字:整數或浮點數,在 ±(253-1)
範圍內的整數。
bigint
用于任意長度的整數。
string
用于字符串:壹個字符串可以包含 0 個或多個字符,所以沒有單獨的單字符類型。
boolean
用于 true
和 false
。
null
用于未知的值 —— 只有壹個 null
值的獨立類型。
undefined
用于未定義的值 —— 只有壹個 undefined
值的獨立類型。
symbol
用于唯壹的標識符。
以及壹種非原始數據類型(複雜數據類型):
object
用于更複雜的數據結構。
我們可以通過 typeof
運算符查看存儲在變量中的數據類型。
通常用作 typeof x
,但 typeof(x)
也可行。
以字符串的形式返回類型名稱,例如 "string"
。
typeof null
會返回 "object"
—— 這是 JavaScript 編程語言的壹個錯誤,實際上它並不是壹個 object
。
在接下來的章節中,我們將重點介紹原始類型值,當妳掌握了原始數據類型後,我們將繼續學習 object
。
重要程度: 5
下面的腳本會輸出什麽?
let name = "Ilya"; alert( `hello ${1}` ); // ? alert( `hello ${"name"}` ); // ? alert( `hello ${name}` ); // ?
反引號將包裝在 ${...}
中的表達式嵌入到了字符串。
let name = "Ilya"; // 表達式爲數字 1 alert( `hello ${1}` ); // hello 1 // 表達式是壹個字符串 "name" alert( `hello ${"name"}` ); // hello name // 表達式是壹個變量,嵌入進去了。 alert( `hello ${name}` ); // hello Ilya