新手必看篇——JS类型判断

在JavaScript开发中,准确判断数据类型是日常编码的高频操作,也是不少初学者容易踩坑的地方。为什么typeof null"object"? instanceof 的原理是什么?有没有一种"万能"的类型判断方法?本文将从原始类型和引用类型出发,循序渐进的带你搞懂这类型判断背后的门道。

一. 先温习JS中的两大类型阵营

在开始讨论之前,我们先快速回顾一下JS中的数据类型划分:

原始类型

string,number,boolaen,null, undefined, bigint, Symbol

它们直接存储于栈中,赋值给变量时是值的拷贝。

引用类型

Array, function, object, Date

它们存储在堆内存中,变量保存的只是内存地址的引用。

因为这两种类型在底层存储和行为的差异,导致它们各自适合不同的判断方式。

二. typeof---------简单直接,但有局限

typeof 操作符是我们最常用的类型判断工具之一。它的特点是:

  • 能准确判断除null以外的所有原始类型

  • 对于引用类型,typeof 统一返回 "object",只有一个特例:函数返回 "function"

也就是说,数组、普通对象、日期对象、正则表达式等统统被识别为 "object"

js 复制代码
typeof []         // "object"
typeof {}         // "object"
typeof new Date() // "object"
typeof /reg/      // "object"
typeof function(){}  // "function"

让人迷惑的 null

js 复制代码
typeof null  // "object"

为什么判断null返回的是object呢?这是因为:typeof 是通过将值转为二进制 ,来判断类型的,二进制前三位是 0 的统一被认为是引用类型 ,在计算机中,所有的引用类型被转为二进制,前三位都是 0(除了函数) ,而 null 转为二进制是一整串 0,所以null被错误判断为了object

三.instanceof------基于原型链的归属判断

1. 只能判断引用类型,无法判断原始类型

3. 它是通过隐式原型链来查找 x 是否隶属于 X 这个类型

js 复制代码
[] instanceof Array        // true
{} instanceof Object       // true
new Date() instanceof Date  // true
function(){} instanceof Function  // true

四. Object.prototype.toString------终极万能判断法

如果你想要一个绝对可靠、能区分所有数据类型 的方法,那非Object.prototype.toString莫属。

原理浅析

每个对象内部都有一个 [[Class]] 属性,它标记了该对象的类型标签 (如 ArrayDateNumberString 等)。当我们调用 Object.prototype.toString 方法时,它会执行以下步骤:

  1. 如果值是 undefined,直接返回 "[object Undefined]"

  2. 如果值是 null,返回 "[object Null]"

  3. 否则,将值转换为一个对象(ToObject(this)),然后读取该对象的 [[Class]] 属性,最后拼接成 "[object " + [[Class]] + "]" 的形式。

由于 Object.prototype.toString 可以被任意对象调用,我们通常使用 callapply 来改变它的 this 指向,使其能直接处理原始值。

js 复制代码
Object.prototype.toString.call(123)     // "[object Number]"
Object.prototype.toString.call("hello") // "[object String]"
Object.prototype.toString.call(true)    // "[object Boolean]"
Object.prototype.toString.call(null)    // "[object Null]"
Object.prototype.toString.call(undefined) // "[object Undefined]"
Object.prototype.toString.call([])       // "[object Array]"
Object.prototype.toString.call({})       // "[object Object]"
Object.prototype.toString.call(new Date()) // "[object Date]"
Object.prototype.toString.call(/reg/)    // "[object RegExp]"
Object.prototype.toString.call(function(){}) // "[object Function]"

五. Array.isArray------专为数组而生

检测数组是最常见的需求之一,虽然Object.prototype.toString.call(arr) === "[object Array]"万无一失,但是数组有一个专门的Array.isArray()方法,更加简单直接。

js 复制代码
Array.isArray([])      // true
Array.isArray({})      // false
Array.isArray(new Array(5))  // true

六.各方法对比总结

方法 适用场景 不足之处
typeof 判断原始类型(除null外)和函数 typeof null"object";无法区分具体的对象类型(数组、日期等)
instanceof 判断某个对象是否由指定构造函数创建 无法判断原始类型
Object.prototype.toString 全场景通用,精准返回每个数据的内置类型 写法稍长,通常需要封装
Array.isArray 专用于判断数组 只解决数组场景
相关推荐
Setsuna_F_Seiei5 小时前
前端的 AI 学习之路 01 之 Agent API 调用 - 和 Agent 的基础对话
前端·人工智能·ai编程
threerocks5 小时前
AI 原生软件开发生命周期手册 - 如何借助 AI,逐阶段改造软件开发生命周期
前端·javascript·后端
徐小夕5 小时前
3分钟从想法到Agent上线:我们开源了一款AI可视化工作流“IDE”
前端·算法·github
ly76897 小时前
JavaScript 从入门到进阶:核心语法、异步编程与工程化实践
开发语言·javascript·ecmascript
why技术7 小时前
eli5,我觉得这个全网在吹的技能,使用体验真的很一般啊。
前端·人工智能·后端
excel7 小时前
记录升级 nuxt3 到 nuxt4 记录
前端
剑胆琴心静水深流8 小时前
全栈之路6---web集成与呈现
前端·vue.js·spring boot·分布式·spring·前端框架·npm
前端snow8 小时前
ai agent -- Memory汇总
前端
ITresearchGuest8 小时前
AI 焦虑下,前端该何去何从
前端·人工智能
沙盘客9 小时前
AFSIM 示例解读(03)· 六自由度飞行仿真 six_dof(下):机场运作与弹道导弹投送
java·javascript·经验分享