JavaScript?原始數據類型和對應的對象類型(內置對象)之間的關系
JavaScript 的原始(primitive)數據類型包括包括數字(Number)、字符串(String)、布爾值(Boolean)、null、undefined、符號(Symbol,ES6 引入)和 BigInt(ES2020 引入)。這些原始數據類型是不可變的,沒有屬性或方法。
在 JavaScript 中,原始數據類型和內置對象(也稱為對象類型或包裝器對象)之間存在一種特殊的關系。
原始數據類型和對應的對象類型之間的關系:
- 原始類型是簡單的數據類型,沒有屬性或方法。
- 對應的對象類型是通過構造函數創建的復雜對象,具有屬性和方法。
- JavaScript 會在需要時自動將原始類型的值包裝成對應的對象類型,以便可以調用方法。
- 這個自動包裝過程通常是透明的,開發者不需要手動進行裝箱或拆箱操作。
- 通常情況下,我們在編程時使用原始數據類型,因為它們更簡單、更快。只有在需要利用對象的屬性和方法時,JavaScript 引擎才會臨時將它們轉換為對象。
理解原始數據類型和對象類型之間的關系需要注意的幾個方面:
- 自動裝箱(Autoboxing):當你對一個原始數據類型的值使用屬性或方法時,JavaScript 會自動將其轉換(裝箱)為對應的對象類型,這樣就可以使用對象提供的方法和屬性。例如,當你對一個字符串原始值調用?.length?屬性時,JavaScript 會臨時將其轉換為?String?對象,然后訪問其?length?屬性。
- 原始值的不可變性:原始數據類型的值是不可變的,這意味著一旦創建,它們的值就不能改變。相反,對象是可變的,你可以改變其屬性和方法。
- 性能考慮:使用原始數據類型通常比使用對象類型更高效,因為原始類型占用的內存更少,且沒有對象的額外開銷。
- 類型轉換:你可以通過調用對象類型的方法來顯式地將原始類型轉換為對象類型,反之亦然。例如,String(123)?會將數字轉換為字符串,而?Number("123")?會將字符串轉換為數字。
JavaScript 提供了一些內置的構造函數,如 Number 和 String,這些構造函數可以用來創建對應原始類型的包裝對象。這些包裝對象是可以包含屬性和方法的復雜數據類型。當你對一個原始類型的值調用方法時,JavaScript 會臨時將其包裝成一個對象,以便你可以調用這些方法。
原始類型的數字是不可變的值。當你對一個原始類型的數字進行操作時,實際上是在創建一個新的數字值。例如:
let num = 10;
num.toFixed(2); // "10.00"
在上面的例子中,toFixed 是一個方法,看起來像是直接被數字字面量 10 調用的。但實際上,JavaScript 在幕后將 10 臨時轉換成了一個 Number 對象,然后在這個對象上調用了 toFixed 方法。這個過程稱為 “裝箱”(boxing)。
Number 對象是通過 Number 構造函數創建的,它包含了數字的屬性和方法。例如:
let numObject = new Number(10);
numObject.toFixed(2); // "10.00"
在這個例子中,numObject 是一個 Number 對象,它是一個包含原始數字值的復雜對象。
原始類型的字符串也是不可變的值。字符串有很多方法,比如 toUpperCase 和 charAt,這些方法可以被字符串字面量直接調用:
let str = "hello";
str.toUpperCase(); // "HELLO"
當調用 str.toUpperCase() 時,原始字符串 "hello" 被臨時包裝成一個 String 對象,然后在這個對象上調用 toUpperCase 方法。完成方法調用后,這個臨時對象就被丟棄了。
String 對象是通過 String 構造函數創建的,它同樣包含了字符串的屬性和方法:
let strObject = new String("hello");
strObject.toUpperCase(); // "HELLO"
在這個例子中,strObject 是一個 String 對象。
需要注意的是,在實際編程中,我們通常直接使用原始數據類型,而不是顯式創建對象類型,因為 JavaScript 引擎會根據需要自動進行裝箱和拆箱操作。
換句話說,在實際編程中,我們通常直接使用原始數據類型,因為它們更簡單、更高效。JavaScript 引擎會在需要時自動進行原始數據類型到對象類型的臨時轉換(裝箱),以便我們可以利用對象上的方法和屬性,這個過程對開發者來說是透明的,通常不需要手動創建這些對象。
并不是每個原始數據類型都有一個直接對應的對象類型,具體情況如下:
Number: 有一個對應的對象類型,即 Number 對象。
String: 有一個對應的對象類型,即 String 對象。
Boolean: 有一個對應的對象類型,即 Boolean 對象。
Symbol: 有一個對應的對象類型,即 Symbol 對象。
BigInt: 有一個對應的對象類型,即 BigInt 對象。
然而,對于 null 和 undefined,情況就不同了:
null: 沒有對應的對象類型。null 表示“沒有值”或“空值”,它通常用于指示變量未指向任何對象。
undefined: 同樣沒有對應的對象類型。undefined 表示變量已聲明但未被初始化。
內置構造函數和它們創建的對象包裝器:
Number: 這個構造函數用于創建數字的對象包裝器。例如,new Number(123) 會創建一個包裝了數字 123 的 Number 對象。
String: 這個構造函數用于創建字符串的對象包裝器。例如,new String("text") 會創建一個包裝了字符串 “text” 的 String 對象。
Boolean: 這個構造函數用于創建布爾值的對象包裝器。例如,new Boolean(true) 會創建一個包裝了布爾值 true 的 Boolean 對象。
Symbol: 用于創建符號的構造函數,它是 ES6 中引入的。例如,Symbol('description') 會創建一個具有描述的新符號。
BigInt: 用于創建大整數的構造函數,它是在 ES2020 中引入的。例如,BigInt(12345678901234567890) 會創建一個 BigInt 對象。