JavaScript是一種弱類型語言,當你給一個變量賦了一個值,該值是什么類型的,那么該變量就是什么類型的,并且你還可以給一個變量賦多種類型的值,也不會報錯,這就是JavaScript的內部機制所決定的,那么當我們在使用一些方法的時候,必須知道該變量是什么類型的,才能調用該變量對應的一些方法,那么我們如何獲取到值的變量呢?
這里我們有三種方法
1.typeof? 2.instanceof?3.Object.prototype.toString? 下面我將詳細講解一下這三個方法
typeof:
作用:判斷一個變量類型
底層原理:js中為了提高性能效率,使用值編碼來存儲值的類型,讀取值編碼當中的類型標簽位,根據標簽值返回對應的類型字符串
類型判斷流程:先區分「直接量」與「指針」
直接量表:
數據類型 | 存儲形式 | 第 0 位 | 類型判定關鍵 |
---|---|---|---|
Boolean | 小整數(SMI) | 0 | 值為?0 ?或?2 ,且最低位為?0 (SMI 標記)。 |
Number(SMI) | 32 位有符號整數(SMI) | 0 | 值非?0 /2 ,且最低位為?0 (SMI 標記)。 |
Undefined | 全局特殊值(單例) | 無 | 直接比較值是否為?undefined ?全局變量,typeof ?直接返回?"undefined" 。 |
指針表:?
數據類型 | 存儲形式 | 低 3 位標簽 | 類型判定關鍵 |
---|---|---|---|
普通?Object | 指針 | 000 | 低 3 位為?000 |
HeapNumber (浮點數) | 指針 | 001 | 低 3 位為?001 |
String | 指針 | 110 | 低 3 位為?110 |
Symbol | 指針 | 100 | 低 3 位為?100 |
BigInt | 指針 | 101 | 低 3 位為?101 |
Function (函數) | 指針 | 011 | 低 3 位為?011 |
null | 空指針 | 000 |
這里null比較特殊,他的低三位和對象object一樣,所以會被typeof誤判為object對象
這里舉一些比較常見的事例:?
console.log(typeof undefined); // 輸出:"undefined"
console.log(typeof null); // 輸出:"object"
console.log(typeof true); // 輸出:"boolean"
console.log(typeof 42); // 輸出:"number"
console.log(typeof "hello"); // 輸出:"string"
console.log(typeof Symbol("key"));// 輸出:"symbol"
console.log(typeof 100n); // 輸出:"bigint"
console.log(typeof (() => {})); // 輸出:"function"
console.log(typeof {}); // 輸出:"object"//特殊情況
console.log(typeof /test/g); // "object"
console.log(typeof Infinity); // "number"
console.log(typeof NaN); // "number"
console.log(typeof undeclaredVar); // "undefined"(不會報錯)
instanceof:
概念:instanceof 是一種操作符,用于判斷一個對象是否是某個類(Class)或接口(Interface)的實例。這里需要注意的是,instanceof只能判斷對象,不能判斷基本類型
原理: instanceof 操作符用于檢測構造函數的 prototype 屬性是否出現在某個實例對象的原型鏈上? 左邊實例對象的內部屬性通過 Object.getPrototypeOf() 方法來訪問[[Prototype]]
//這里表示instanceof不能直接用于基本類型
console.log(42 instanceof Number); // false//可以將基本類型通過內置構造函數包裝成對象
const numObj = new Number(42);
console.log(numObj instanceof Number); // trueconsole.log([] instanceof Array); // true
console.log([] instanceof Object); // true
console.log({} instanceof Object); // true
Object.prototype.toString:
概念:
這個方法可以判斷一個變量的具體類型,是最精確的檢測方式,返回的是一個【object type】格式字符串,它可以識別到所有內置對象的類型
使用方法:
// 基本類型和內置對象
Object.prototype.toString.call({}); // [object Object]
Object.prototype.toString.call([]); // [object Array]
Object.prototype.toString.call(new Date()); // [object Date]
Object.prototype.toString.call(new MyClass()); // [object Object] (默認)
和typeof對比:
類型 | typeof ?結果 | Object.prototype.toString.call() ?結果 |
---|---|---|
[] | "object" | [object Array] |
new Date() | "object" | [object Date] |
/abc/ | "object" | [object RegExp] |
null | "object" | [object Null] |
undefined | "undefined" | [object Undefined] |
Symbol(1) | "symbol" | [object Symbol] |