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

