JS判断数据类型的方法有哪些?
哈喽!今天心血来潮给大家带来了《JS如何判断数据类型?》,想必大家应该对文章都不陌生吧,那么阅读本文就都不会很困难,以下内容主要涉及到,若是你正在学习文章,千万别错过这篇文章~希望能帮助到你!
判断JavaScript数据类型需根据场景选择方法:1. typeof适用于基本类型判断,但对null和对象均返回'object',存在局限;2. instanceof通过原型链检测对象类型,适合判断自定义类或内置对象如Array、Date,但在跨全局环境时不可靠;3. Object.prototype.toString.call()最精确,能区分所有内置类型,推荐用于需要高准确性的场景;4. constructor属性易被修改,不推荐依赖。typeof null返回'object'是因早期实现中null的位模式与对象标签冲突,属历史遗留问题。判断数组应优先使用Array.isArray(),因其不依赖构造函数实例,可避免跨环境失效。判断纯对象推荐使用Object.prototype.toString.call(value) === '[object Object]',该方法能准确排除数组、函数等非普通对象,且兼容性强,是目前最可靠的方案。
在JavaScript里,判断数据类型这事儿,说简单也简单,说复杂也挺复杂。简单在于我们有几个内置的工具,复杂在于它们各自都有点“脾气”或者说“陷阱”,用不对地方就可能踩坑。核心来说,我们通常会用到typeof
、instanceof
、Object.prototype.toString.call()
,以及偶尔会考虑constructor
属性。每种方法都有它的适用场景和局限性,理解这些,才能在实际开发中游刃有余。

解决方案
判断JavaScript数据类型,并没有一个“万能药”,而是需要根据具体场景和你想判断的“类型”深度来选择合适的方法。
typeof
操作符: 这是最直观也最常用的一个。它能很好地识别基本数据类型:'string'
、'number'
、'boolean'
、'symbol'
、'bigint'
、'undefined'
。对于函数,它会返回'function'
,这算是它一个比较特殊的待遇,毕竟函数在JS里也是一种特殊的对象。然而,它的一个大坑是,对于所有非函数对象(包括数组、null
),它统一返回'object'
。所以,如果你想区分数组和普通对象,或者判断一个值是不是null
,typeof
就显得力不从心了。console.log(typeof "hello"); // "string" console.log(typeof 123); // "number" console.log(typeof true); // "boolean" console.log(typeof undefined); // "undefined" console.log(typeof Symbol('id')); // "symbol" console.log(typeof 10n); // "bigint" console.log(typeof {}); // "object" console.log(typeof []); // "object" console.log(typeof null); // "object" —— 经典的坑 console.log(typeof function(){}); // "function"
instanceof
操作符: 这个操作符主要用来检测构造函数的prototype
属性是否出现在某个实例对象的原型链上。它非常适合用来判断一个对象是不是某个特定类的实例,比如判断一个变量是不是Array
、Date
、RegExp
等内置构造函数的实例,或者你自己定义的类的实例。但它也有局限性,它不能用于判断基本数据类型,而且在多全局环境(比如iframe之间)判断对象时可能会失效,因为每个iframe都有自己的全局对象和构造函数。let arr = [1, 2, 3]; let obj = {}; let date = new Date(); console.log(arr instanceof Array); // true console.log(obj instanceof Object); // true console.log(date instanceof Date); // true console.log(arr instanceof Object); // true (因为数组也是对象) console.log("hello" instanceof String); // false (基本类型不是String对象的实例)
Object.prototype.toString.call()
方法: 这绝对是判断数据类型最“靠谱”的方法之一,尤其是在需要精确区分内置对象类型时。Object.prototype.toString
方法在执行时,会返回一个表示该对象类型的字符串,格式通常是"[object Type]"
,其中Type
是对象的内部[[Class]]
属性值。通过call
方法,我们可以强制让任何值调用这个toString
方法,从而得到其准确的内部类型描述。console.log(Object.prototype.toString.call("hello")); // "[object String]" console.log(Object.prototype.toString.call(123)); // "[object Number]" console.log(Object.prototype.toString.call(true)); // "[object Boolean]" console.log(Object.prototype.toString.call(undefined)); // "[object Undefined]" console.log(Object.prototype.toString.call(null)); // "[object Null]" console.log(Object.prototype.toString.call({})); // "[object Object]" console.log(Object.prototype.toString.call([])); // "[object Array]" console.log(Object.prototype.toString.call(function(){})); // "[object Function]" console.log(Object.prototype.toString.call(new Date())); // "[object Date]" console.log(Object.prototype.toString.call(new RegExp())); // "[object RegExp]" console.log(Object.prototype.toString.call(Symbol('id'))); // "[object Symbol]" console.log(Object.prototype.toString.call(10n)); // "[object BigInt]"
这是我个人最推荐的方法,因为它几乎能覆盖所有内置类型,并且结果非常精确。
constructor
属性: 每个对象都有一个constructor
属性,指向创建该实例的构造函数。你可以通过它来判断类型。let arr = [1, 2]; let obj = {}; console.log(arr.constructor === Array); // true console.log(obj.constructor === Object); // true
然而,这个方法并不是特别可靠。
constructor
属性是可以被修改的,或者在原型链上被覆盖,这会影响判断结果。比如,一个自定义类继承了Array
,它的constructor
可能指向它自己的类,而不是Array
。所以,除非你对代码的控制力非常强,否则不建议过度依赖它。
为什么typeof null会返回'object'?这算是一个设计缺陷吗?
这确实是JavaScript里一个长久以来的“梗”,typeof null
返回 'object'
。从现代编程语言的设计角度看,这无疑是一个不一致的地方,甚至可以说是一个“历史遗留问题”或者“设计缺陷”。但要说它是缺陷,不如说它是一个“意外”。
这个行为的根源在于JavaScript的早期实现。在JavaScript的第一个版本中,值是以32位字来存储的。其中,低位(或某些位)被用来表示值的类型标签。
- 对象的类型标签是
000
。 null
被表示为机器码的0
。 所以,当typeof
操作符检查null
时,它看到的是000
这个类型标签(因为0
的二进制表示就是全零),因此错误地判断它为'object'
。
这确实不是一个有意的设计,而是一个实现上的巧合。修复它会破坏大量的现有代码,因为很多老旧的JavaScript代码可能已经依赖了这个行为(虽然这听起来有点不可思议,但确实如此)。因此,为了保持向后兼容性,这个“bug”或者说“怪癖”就被保留了下来。
在实际开发中,我们通常会先判断一个值是否为null
,再进行typeof
判断,以避免这个误区:
function checkType(value) { if (value === null) { return "null"; } return typeof value; } console.log(checkType(null)); // "null" console.log(checkType({})); // "object"
判断数组类型时,为什么Array.isArray()比instanceof更可靠?
在判断一个变量是否是数组时,Array.isArray()
无疑是黄金标准,它比instanceof Array
更可靠。这背后的原因主要在于JavaScript的“领域”概念,或者更通俗地说,是“跨iframe”或“跨全局环境”的问题。
想象一下,你在一个网页里嵌入了一个iframe。这个iframe内部有自己的JavaScript运行环境,它有自己的全局对象、自己的Array
构造函数。
如果你在父页面创建了一个数组parentArray = []
,然后把它传递给iframe。在iframe内部,如果你尝试parentArray instanceof Array
,结果可能会是false
。这是因为parentArray
是由父页面的Array
构造函数创建的,而iframe内部的Array
构造函数是它自己环境里的,两者虽然名字相同,但它们在内存中是不同的对象。instanceof
的原理是检查对象的原型链是否包含构造函数的prototype
属性,但在这种跨域(这里指不同的JavaScript全局上下文)的情况下,它们的prototype
对象并不是同一个。
Array.isArray()
则不同,它不依赖于具体的构造函数实例。它在底层会检查对象的内部[[Class]]
属性(在ES6之后,这个概念被Symbol.toStringTag
取代,但原理类似),或者其他更底层的、与特定全局环境无关的机制来判断。简单来说,它会直接问“你是不是一个真正的数组?”而不是“你是通过我这个Array构造函数创建的吗?”
// 假设这是在浏览器环境中,通过iframe模拟跨全局环境 const iframe = document.createElement('iframe'); document.body.appendChild(iframe); const iframeWin = iframe.contentWindow; // 在iframe中创建的数组 const iframeArray = iframeWin.Array(1, 2, 3); // 在主页面中判断 console.log(iframeArray instanceof Array); // 可能会是 false (取决于浏览器实现和沙箱策略) console.log(Array.isArray(iframeArray)); // true (始终可靠) // 清理 document.body.removeChild(iframe);
因此,为了确保代码在各种复杂环境下(尤其是在涉及多窗口、iframe、Web Workers等场景)的健壮性,始终推荐使用Array.isArray()
来判断数组。
如何判断一个变量是纯粹的JavaScript对象(即{}或new Object()创建的)?
要判断一个变量是否是“纯粹”的JavaScript对象,也就是那些通过对象字面量{}
或new Object()
创建的,而不是数组、函数、日期、正则表达式等特定类型的对象,这是一个常见的需求。typeof
在这里会返回'object'
,但它并不能区分这些具体类型。
最可靠且我个人常用的方法,依然是借助Object.prototype.toString.call()
:
function isPlainObject(value) { if (typeof value !== 'object' || value === null) { return false; } return Object.prototype.toString.call(value) === '[object Object]'; } console.log(isPlainObject({})); // true console.log(isPlainObject(new Object())); // true console.log(isPlainObject([])); // false ([object Array]) console.log(isPlainObject(new Date())); // false ([object Date]) console.log(isPlainObject(function(){})); // false ([object Function]) console.log(isPlainObject(null)); // false console.log(isPlainObject(123)); // false
这个方法之所以可靠,是因为Object.prototype.toString
在非普通对象上会返回其特有的[[Class]]
字符串,而只有纯粹的Object
实例才会返回[object Object]
。
除了这个,还有一些其他思路,但各有其局限性:
检查原型链: 可以检查对象的原型是否直接等于
Object.prototype
。function isPureObjectByProto(value) { if (typeof value !== 'object' || value === null) { return false; } let proto = Object.getPrototypeOf(value); // 如果没有原型 (比如Object.create(null)),或者原型就是Object.prototype return proto === null || proto === Object.prototype; } console.log(isPureObjectByProto({})); // true console.log(isPureObjectByProto(Object.create(null))); // true (无原型对象) console.log(isPureObjectByProto([])); // false (原型是Array.prototype)
这个方法也挺好,尤其能处理
Object.create(null)
创建的“纯粹”对象(它们没有原型链,因此Object.getPrototypeOf
返回null
)。但如果一个对象是通过继承某个自定义类而来的,即使它看起来像一个普通对象,Object.getPrototypeOf
也不会是Object.prototype
。结合
constructor
属性(不推荐): 虽然前面说了constructor
不靠谱,但有时也会被用来尝试判断。function isPlainObjectByConstructor(value) { if (typeof value !== 'object' || value === null) { return false; } // 还要排除像Date, Array等内置对象 return value.constructor === Object; } console.log(isPlainObjectByConstructor({})); // true console.log(isPlainObjectByConstructor([])); // false // 但如果constructor被修改,或者来自不同的iframe,就会出问题
这个方法过于脆弱,因为
constructor
属性太容易被篡改或继承链影响。
综合来看,判断纯粹的JavaScript对象,Object.prototype.toString.call(value) === '[object Object]'
依然是最稳健、最推荐的做法。它简洁明了,且在各种复杂场景下都能给出准确的判断。
好了,本文到此结束,带大家了解了《JS判断数据类型的方法有哪些?》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多文章知识!

- 上一篇
- CSS混合模式详解:mix-blend-mode使用教程

- 下一篇
- HTMLmargin设置技巧与应用详解
-
- 文章 · 前端 | 6分钟前 |
- JS修改对象原型的实用方法
- 158浏览 收藏
-
- 文章 · 前端 | 10分钟前 |
- HTML标签大全推荐,10个实用标签详解
- 266浏览 收藏
-
- 文章 · 前端 | 11分钟前 |
- JS用Object.fromEntries转换键值对
- 119浏览 收藏
-
- 文章 · 前端 | 12分钟前 |
- Material-UI多选框全选技巧详解
- 405浏览 收藏
-
- 文章 · 前端 | 14分钟前 |
- BOM模态对话框实现方法详解
- 415浏览 收藏
-
- 文章 · 前端 | 16分钟前 |
- HTML多语言实现方法及工具推荐
- 279浏览 收藏
-
- 文章 · 前端 | 18分钟前 |
- CSSborder属性全面解析
- 184浏览 收藏
-
- 文章 · 前端 | 21分钟前 |
- JavaScript获取HTML元素内容的几种方法
- 104浏览 收藏
-
- 文章 · 前端 | 26分钟前 | 性能优化 比较函数 多条件排序 JS对象数组排序 Array.sort()
- JS数组对象排序技巧全解析
- 210浏览 收藏
-
- 文章 · 前端 | 27分钟前 | JavaScript 性能优化 Transition @keyframes CSS数据可视化动画
- CSS数据动画技巧全解析
- 124浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 511次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 498次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
-
- 千音漫语
- 千音漫语,北京熠声科技倾力打造的智能声音创作助手,提供AI配音、音视频翻译、语音识别、声音克隆等强大功能,助力有声书制作、视频创作、教育培训等领域,官网:https://qianyin123.com
- 100次使用
-
- MiniWork
- MiniWork是一款智能高效的AI工具平台,专为提升工作与学习效率而设计。整合文本处理、图像生成、营销策划及运营管理等多元AI工具,提供精准智能解决方案,让复杂工作简单高效。
- 92次使用
-
- NoCode
- NoCode (nocode.cn)是领先的无代码开发平台,通过拖放、AI对话等简单操作,助您快速创建各类应用、网站与管理系统。无需编程知识,轻松实现个人生活、商业经营、企业管理多场景需求,大幅降低开发门槛,高效低成本。
- 111次使用
-
- 达医智影
- 达医智影,阿里巴巴达摩院医疗AI创新力作。全球率先利用平扫CT实现“一扫多筛”,仅一次CT扫描即可高效识别多种癌症、急症及慢病,为疾病早期发现提供智能、精准的AI影像早筛解决方案。
- 103次使用
-
- 智慧芽Eureka
- 智慧芽Eureka,专为技术创新打造的AI Agent平台。深度理解专利、研发、生物医药、材料、科创等复杂场景,通过专家级AI Agent精准执行任务,智能化工作流解放70%生产力,让您专注核心创新。
- 104次使用
-
- 优化用户界面体验的秘密武器:CSS开发项目经验大揭秘
- 2023-11-03 501浏览
-
- 使用微信小程序实现图片轮播特效
- 2023-11-21 501浏览
-
- 解析sessionStorage的存储能力与限制
- 2024-01-11 501浏览
-
- 探索冒泡活动对于团队合作的推动力
- 2024-01-13 501浏览
-
- UI设计中为何选择绝对定位的智慧之道
- 2024-02-03 501浏览