JS類型判斷之typeof、instanceof與toString示例詳解
前言
在 JavaScript 的世界里,準確判斷一個變量的類型并不像看上去那么簡單。為什么 typeof null 是 object?為什么 instanceof 不能判斷基本類型?本文將帶你通過底層邏輯徹底搞定這些面試重難點。
一、 typeof:快速但有“缺陷”的選擇
typeof 是最常用的判斷方式,它直接返回一個表示類型的字符串。
1. 判斷表現(xiàn)
基本類型:除了
null之外,都能顯示正確結果(string,number,boolean,undefined,symbol,bigint)。引用類型:
- 函數(shù):返回
"function"。 - 其他(數(shù)組、正則、日期、普通對象) :統(tǒng)一返回
"object"。
- 函數(shù):返回
2. 這里的坑:為什么 typeof null === 'object'?
底層原理: JavaScript 的底層變量是使用二進制存儲的。為了提高性能,引擎通過二進制的前三位(Type Tag)來判斷類型:
000:對象(Object)1:整數(shù)010:浮點數(shù)100:字符串110:布爾值
而 null 的所有二進制位都是 0,因此它的前三位也是 000。早期的 JS 實現(xiàn)中沒有對 null 進行特判,導致它被誤判為了對象。這是一個歷史遺留的 Bug,但為了兼容性一直沒有修復。
二、 instanceof:基于原型鏈的“探親”
instanceof 可以判斷對象是屬于哪種類型,它的內(nèi)部機制是通過判斷對象的原型鏈中是不是能找到該類型的 prototype.
1. 查找機制
只要右邊變量的 prototype 在左邊變量的原型鏈上就會返回ture,因此instanceof 在查找的過程中會遍歷左邊變量的原型鏈,直到找到右邊變量的 prototype,如果原型鏈遍歷完都沒有找到,就會返回 false,告訴我們左邊變量并不是右邊變量的實例
2. 手寫實現(xiàn)(面試??迹?/h3>
手寫 instanceof 的核心在于循環(huán)向上遍歷原型鏈。
function myInstanceof(obj, func) {
if (typeof obj !== 'object' && typeof obj !== 'function') {
return false;
}
let proto = obj.__proto__;
const prototype = func.prototype;
while (proto !== prototype) {
if (proto === null) {
return false;
}
proto = proto.__proto__;
}
return true;
}
const date = new Date();
console.log(myInstanceof(date, Object)); // true
console.log(myInstanceof([1, 2], Array)); // true三、 終極方案:Object.prototype.toString
如果你需要一個萬能、精準的判斷方式,那么非它莫屬。
1. 原理
調(diào)用該方法會返回一個格式為 [object Type] 的字符串,其中 Type 就是該值的內(nèi)部屬性 [[Class]]。
2. 測試表現(xiàn)
const toString = Object.prototype.toString;
console.log(toString.call(Math)); // [object Math]
console.log(toString.call('a')); // [object String]
console.log(toString.call(null)); // [object Null]
console.log(toString.call(undefined)); // [object Undefined]
console.log(toString.call([])); // [object Array]
console.log(toString.call(new Date())); // [object Date]四、 面試模擬題(實戰(zhàn)演練)
Q1:如何判斷一個變量是否是數(shù)組?
參考回答:
Array.isArray(arr)(首選,ES6標準方法)。Object.prototype.toString.call(arr) === '[object Array]'(最通用)。arr instanceof Array(注意:如果是在跨 iframe 環(huán)境下,原型鏈不同可能會失效)。
Q2:typeof []和typeof {}的結果分別是什么?
參考回答: 都是 "object"。因為 typeof 除了函數(shù)以外,對于所有的引用類型都會返回 "object"。
Q3:執(zhí)行2 instanceof Number的結果是什么?為什么?
參考回答: 結果是 false。 因為 instanceof 只能用于檢測對象實例。數(shù)字 2 是原始值(Primitive),它沒有原型鏈。如果想讓它返回 true,需要寫成 new Number(2) instanceof Number。
總結
typeof:適合判斷基本類型(除 null)和函數(shù)。instanceof:適合判斷對象之間的繼承關系。toString:適合需要百分百準確判斷類型的場景。
到此這篇關于JS類型判斷之typeof、instanceof與toString的文章就介紹到這了,更多相關JS類型判斷typeof、instanceof與toString內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
JavaScript使用encodeURI()和decodeURI()獲取字符串值的方法
這篇文章主要介紹了JavaScript使用encodeURI()和decodeURI()獲取字符串值的方法,實例分析了encodeURI()和decodeURI()函數(shù)解析字符串的相關技巧,需要的朋友可以參考下2015-08-08
基于js里調(diào)用函數(shù)時,函數(shù)名帶括號和不帶括號的區(qū)別
下面小編就為大家?guī)硪黄趈s里調(diào)用函數(shù)時,函數(shù)名帶括號和不帶括號的區(qū)別。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-07-07
???????基于el-table和el-pagination實現(xiàn)數(shù)據(jù)的分頁效果流程詳解
本文主要介紹了???????基于el-table和el-pagination實現(xiàn)數(shù)據(jù)的分頁效果,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-11-11
JavaScript時間戳與時間相互轉(zhuǎn)換的常用方法
這篇文章主要介紹了JavaScript時間戳與時間相互轉(zhuǎn)換的常用方法,包括獲取當前時間戳、時間戳轉(zhuǎn)時間對象、時間戳轉(zhuǎn)格式化字符串、時間字符串轉(zhuǎn)時間戳等,還討論了常見應用場景如計算時間差、倒計時和UTC與本地時間互轉(zhuǎn),需要的朋友可以參考下2025-04-04

