原文合集地址如下,有需要的朋友可以關注
本文地址
數據類型
JavaScript的數據類型有7中,包括6個基本類型和一個引用類型
基本數據類型:number, string, boolean, null, undefined, symbol
引用數據類型:object(數組、對象、函數、正則等)
基本數據類型和引用數據類型的區別
- 存儲方式
基本類型:基本數據類型的值直接存儲在改變量所分配的內存空間中,它們是簡單數據類型,占用的空間小
引用類型:引用數據類型的值存儲在堆內存中,變量存儲的是對象在堆內存的地址,而不是實際的值,所以引用數據的大小不固定, 可以包含大量數據。 - 賦值行為
基本類型:將一個基本數據類型賦值給另一個變量,直接將該值的副本賦值給新的變量
引用類型:而將引用數據類型的變量賦值給另一個變量,是將該引用類型的地址給另一個變量,不是直接的值,兩個變量指向同一個數據,當修改另一個變量時,此變量的值也會跟著變。 - 比較方式
基本數據類型:基本數據類型的值通過它們的實際值進行比較。
引用數據類型:引用數據類型的值比較的是它們在內存中的地址(引用),而不是實際的值。因此,即使兩個對象具有相同的屬性和值,它們在內存中是不同的對象,比較結果會是 false。
基本數據類型:
let num1 = 42;
let num2 = num1; // 復制值,num2 現在是 42 的副本
num1 = 100; // 修改 num1 的值不會影響 num2console.log(num1); // 輸出 100
console.log(num2); // 輸出 42
引用數據類型:
const obj1 = { name: "John" };
const obj2 = obj1; // 復制引用,obj2 指向 obj1 引用的對象obj1.name = "Alice"; // 修改 obj1 的屬性,也會影響 obj2console.log(obj1.name); // 輸出 "Alice"
console.log(obj2.name); // 輸出 "Alice",因為 obj2 指向與 obj1 相同的對象
判斷變量的數據類型
typeof
typeof運算符用來獲取數據的類型。但是對于 null 返回的是 “object”,這是歷史遺留問題,可能會導致誤判。
對于函數返回的是 “function”,但函數也是對象的一種,因此不能準確區分一個變量是簡單的函數還是其他類型的對象。
typeof "hello" // 返回 "string"
typeof 42 // 返回 "number"
typeof true // 返回 "boolean"
typeof undefined // 返回 "undefined"
typeof null // 返回 "object"
typeof [] // 返回 "object"
typeof {} // 返回 "object"
typeof function(){} // 返回 "function"
instanceof
instanceof 運算符用于檢查一個對象是否屬于某個特定類的實例。
但是它只能判斷賦復雜數據類型,不能判斷基本數據類型。
const myArray = [];
const myDate = new Date();console.log(myArray instanceof Array); // 輸出 true
console.log(myArray instanceof Object); // 輸出 true,因為 Array 是 Object 的子類
console.log(myDate instanceof Date); // 輸出 true
console.log(myDate instanceof Object); // 輸出 true,因為 Date 是 Object 的子類
Array.isArray()
Array.isArray()用于判斷值是否為數組類型。
console.log(Array.isArray([])); // 輸出 true
console.log(Array.isArray({})); // 輸出 false
Object.prototype.toString.call()
使用 Object.prototype.toString.call() 方法:這是一種通用的方法,可以檢測幾乎所有的數據類型。
console.log(Object.prototype.toString.call("hello")); // 輸出 "[object String]"
console.log(Object.prototype.toString.call(42)); // 輸出 "[object Number]"
console.log(Object.prototype.toString.call(true)); // 輸出 "[object Boolean]"
console.log(Object.prototype.toString.call(undefined)); // 輸出 "[object Undefined]"
console.log(Object.prototype.toString.call(null)); // 輸出 "[object Null]"
console.log(Object.prototype.toString.call([])); // 輸出 "[object Array]"
console.log(Object.prototype.toString.call({})); // 輸出 "[object Object]"
console.log(Object.prototype.toString.call(function () {})); // 輸出 "[object Function]"
console.log(Object.prototype.toString.call(new Date())); // 輸出 "[object Date]"
雖然上述方法在很多情況下可以滿足數據類型判斷的需求,但它們也有一些弊端需要注意:
-
typeof
的問題:- 對于
null
返回的是"object"
,這是歷史遺留問題,可能會導致誤判。例如,無法準確判斷一個變量是null
還是對象。 - 對于函數返回的是
"function"
,但函數也是對象的一種,因此不能準確區分一個變量是簡單的函數還是其他類型的對象。
- 對于
-
instanceof
的問題:instanceof
只能檢測對象類型,并且還要考慮原型鏈。如果對象是在不同的全局上下文中創建的,或者涉及多個框架,instanceof
可能會失效。- 不能判斷基本數據類型,如字符串、數字、布爾值等。
-
Array.isArray()
的問題:Array.isArray()
只能判斷數組類型,不能判斷其他對象類型。
-
Object.prototype.toString.call()
的問題:- 這種方法雖然可以準確判斷大部分類型,但使用起來較為繁瑣,需要額外的調用,并且不夠直觀。
- 如果出現自定義類的實例,
Object.prototype.toString.call()
只會返回"[object Object]"
,無法具體判斷其屬于哪個類。
封裝判斷變量的數據類型函數
這里分別用了typeof和Object.prototype.toString.call()方法。
/*** @param 要判斷類型的值* @returns 數據類型*/
export const getDataType = (value: any) => {if (typeof value === "object") {if (value === null) return "null";if (Array.isArray(value)) return "array";return "object";}return typeof value;
};export const getDataType2 = (value: any) => {const type = Object.prototype.toString.call(value);if (type === "[object String]") return "string";if (type === "[object Number]") return "number";if (type === "[object Boolean]") return "boolean";if (type === "[object Undefined]") return "undefined";if (type === "[object Null]") return "null";if (type === "[object Array]") return "array";if (type === "[object Object]") return "object";if (type === "[object Function]") return "function";if (type === "[Object Date]") return "date";
};