类型判断什么时候用 typeof?

typeof 是 JavaScript 中最常用的类型判断运算符,但它有几个致命的盲区和历史包袱

1. null 被误判为 'object'(最著名的历史 bug)

2. 无法区分数组和普通对象

3. NaN 被判定为 'number'

4. 无法区分普通函数和类

class 本质上是函数的语法糖,typeof 无法区分"普通函数"和"类构造函数"。

5. 无法区分包装对象和原始值(严格来说不算 bug,但容易混淆)

什么时候用 typeof

typeof 不是不能用,而是只适合判断原始类型和函数

一旦涉及对象的具体类型判断,立即换 Object.prototype.toString.call

Object.prototype.toString.call()

JavaScript 中最可靠的内置类型判断方法 ,江湖人称「类型判断的终极武器」。

返回格式永远是 [object Xxx] ,其中 Xxx 就是该值的内部 [[Class]]Symbol.toStringTag

为什么它这么准?

1. 每个对象都继承了 toString

JavaScript 中,几乎所有对象都自带 toString 方法,但很多都重写了

JavaScript

vbscript 复制代码
[1,2,3].toString()        // "1,2,3"  ← Array 重写了
({a:1}).toString()        // "[object Object]"  ← Object 默认
(function(){}).toString() // "function(){}"  ← Function 重写了

直接调用对象的 toString,得到的往往是该对象自定义的字符串,无法判断类型

2. Object.prototype.toString 是「原版」

Object.prototype.toString 没有被重写,它的行为是固定的:

读取被调用对象的内部 [[Class]] 属性,返回 [object ClassName]

但问题是,如果你直接写:

JavaScript

vbscript 复制代码
Object.prototype.toString([])    
// 等同于 [].toString(),返回 "1,2,3"

因为 Object.prototype.toString 里的 this 指向了数组,数组又重写了 toString,所以结果还是乱的。

3. .call() 强制绑定 this

JavaScript

css 复制代码
Object.prototype.toString.call([])

这里用 .call([])this 强制绑定到数组实例上,但调用的是 Object.prototype 上的原版 toString,数组自己的重写版本被绕过了。

于是原版 toString 读取数组的内部 [[Class]],返回 [object Array]

Object.prototype.toString.call(x) 通过绕过对象重写、强制绑定 this、读取内部 \[Class] 的方式,返回最准确的类型标签。它是 JS 中判断内置类型最 robust 的方法,没有之一。

相关推荐
幸运小圣26 分钟前
JavaScript 关键字与保留字学习笔记详细讲解,一篇get ✅【JavaScript查缺补漏】
javascript·笔记·学习
独立开发之道2 小时前
Three.js 创建 VR 内容:四步把一个普通 3D 场景送进头显
javascript·3d·vr
Coodor3 小时前
在前端如何转换IC卡卡号格式
前端·javascript·nfc·卡号格式
百慕大三角3 小时前
给 SPA 加页面切换动画:View Transitions API 从入门到实战
前端·javascript
Hilaku3 小时前
Bun 真的能取代 Node.js 吗?
前端·javascript·程序员
开开心心就好4 小时前
手机悬屏翻译工具外语游戏漫画APP全覆盖
android·前端·javascript·python·游戏·pdf·html
光影少年5 小时前
react navite封装一个RN 通用按钮组件
前端·javascript·react native·react.js·前端框架
独立开发之道5 小时前
【three.js教程】Three.js 矩阵变换:position/quaternion/scale 和 matrix 到底怎么配合
开发语言·javascript·矩阵
nicole bai5 小时前
dialog封装
前端·javascript·vue.js