JavaScript中数据类型检测的全部方式

目录

一、基础检测方法

1. typeof 操作符

2. instanceof 运算符

3. Object.prototype.toString.call()

二、进阶检测技巧

1. 特定类型检测方法

2. 构造函数属性检测

3. ES6 Symbol.toStringTag 自定义类型

三、特殊类型检测场景

1. null 与 undefined 检测

2. 纯对象检测(排除数组等)

3. 跨窗口对象检测

四、现代框架的检测方案

1. Lodash类型检测方法

2. Vue源码中的检测逻辑

五、类型检测方案对比

六、最佳实践建议


从基础到进阶,全面解析类型检测的8种方案

JavaScript作为动态类型语言,类型检测是开发中最重要的基础技能之一。本文将系统梳理从基础到高级的所有类型检测方法,通过代码示例对比不同方案的适用场景,并揭示现代框架的类型检测底层原理。


一、基础检测方法

1. typeof 操作符

原理:返回值的类型标签(底层二进制判断)
特点

  • 对原始类型有效,但对null和对象类型判断不准

typeof 'str'    // 'string'  
typeof 42       // 'number'  
typeof true     // 'boolean'  
typeof undefined // 'undefined'  
typeof Symbol() // 'symbol'  
typeof null     // 'object' (历史遗留问题)  
typeof []       // 'object'  
typeof {}       // 'object'  
typeof function(){} // 'function'  
2. instanceof 运算符

原理:检测构造函数的prototype是否在对象的原型链上
适用场景:检测自定义对象类型


[] instanceof Array          // true  
new Date() instanceof Date   // true  

function Person() {}  
const p = new Person();  
p instanceof Person          // true  

// 局限性:跨窗口对象检测失效  
iframe.contentWindow.Array !== window.Array  
iframeArray instanceof Array // false  
3. Object.prototype.toString.call()

原理:调用对象内部的[[Class]]属性(ES5规范)
返回值[object Type]格式字符串

Object.prototype.toString.call('')      // [object String]  
Object.prototype.toString.call(42)     // [object Number]  
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]  

// 封装通用检测函数  
function getType(obj) {  
  return Object.prototype.toString.call(obj)  
    .slice(8, -1)  
    .toLowerCase();  
}  

二、进阶检测技巧

1. 特定类型检测方法
  • 数组检测

    Array.isArray([]) // true(ES5+最佳方案)  
    // Polyfill写法:  
    if (!Array.isArray) {  
      Array.isArray = arg => Object.prototype.toString.call(arg) === '[object Array]';  
    }  

  • NaN检测

    Number.isNaN(NaN) // true(ES6+)  
    // 兼容方案:  
    function isNaN(val) {  
      return val !== val;  
    }  

2. 构造函数属性检测

[].constructor === Array   // true  
{}.constructor === Object  // true  

// 风险:constructor属性可被修改  
function Test() {}  
const obj = new Test();  
obj.constructor = Object;  
obj.constructor === Object // true  
3. ES6 Symbol.toStringTag 自定义类型

允许对象自定义toString标签:

const myObj = {  
  [Symbol.toStringTag]: 'MyCustomType'  
};  
Object.prototype.toString.call(myObj) // [object MyCustomType]  

// 内置对象的应用:  
Object.prototype.toString.call(new Promise(() => {})) // [object Promise]  

三、特殊类型检测场景

1. null 与 undefined 检测

// 安全检测undefined(避免未声明报错)  
typeof variable === 'undefined'  

// 检测null  
variable === null  

// 同时检测null和undefined  
variable == null  
2. 纯对象检测(排除数组等)

function isPlainObject(obj) {  
  return Object.prototype.toString.call(obj) === '[object Object]' &&  
    Object.getPrototypeOf(obj) === Object.prototype;  
}  

isPlainObject({})     // true  
isPlainObject([])     // false  
isPlainObject(null)   // false  
3. 跨窗口对象检测

// 安全检测数组(跨iframe场景)  
function isArray(value) {  
  return Object.prototype.toString.call(value) === '[object Array]';  
}  

四、现代框架的检测方案

1. Lodash类型检测方法

_.isObject({})         // true  
_.isPlainObject({})    // true(纯对象)  
_.isElement(document.body) // true(DOM元素)  
_.isMap(new Map())     // true  
2. Vue源码中的检测逻辑

// vue-next源码节选  
export const isArray = Array.isArray  
export const isMap = (val: unknown): val is Map<any, any> =>  
  toTypeString(val) === '[object Map]'  
export const isSet = (val: unknown): val is Set<any> =>  
  toTypeString(val) === '[object Set]'  

五、类型检测方案对比

检测方式优点缺点推荐使用场景
typeof快速检测原始类型无法区分对象类型检测undefined、函数
instanceof适合自定义类型跨窗口失效、不适用于原始类型检测已知构造函数对象
Object.prototype.toString最全面准确的方案代码较长需要精确类型判断
专用检测方法语义明确需要记忆多个API数组、NaN等特定类型

六、最佳实践建议

  1. 基础场景

    • 优先使用typeof检测原始类型(除null

    • 使用Array.isArray()检测数组

  2. 精确判断

    • 使用Object.prototype.toString.call()获取精确类型

  3. 框架开发

    • 结合Symbol.toStringTag自定义对象类型标签

    • 使用Map/Set等内置类型的专用检测方法

  4. 安全检测

    • 使用variable == null同时检测nullundefined

    • 避免直接访问未声明变量的属性

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/968533.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ATF系统安全从入门到精通

CSDN学院课程连接&#xff1a;https://edu.csdn.net/course/detail/39573

Linux内核实时机制x - 中断响应测试 Cyclictest分析1

Linux内核实时机制x - 中断响应测试Cyclitest 1 实时性测试工具 rt-test 1.1 源码下载 1.下载源码&#xff1a; ~/0-code/5.15$ git clone git://git.kernel.org/pub/scm/utils/rt-tests/rt-tests.git 正克隆到 rt-tests... remote: Enumerating objects: 5534, done. remot…

实现限制同一个账号最多只能在3个客户端(有电脑、手机等)登录(附关键源码)

如上图&#xff0c;我的百度网盘已登录设备列表&#xff0c;有一个手机&#xff0c;2个windows客户端。手机设备有型号、最后登录时间、IP等。windows客户端信息有最后登录时间、操作系统类型、IP地址等。这些具体是如何实现的&#xff1f;下面分别给出android APP中采集手机信…

如何获取,CPU,GPU,硬盘,网卡,内存等硬件性能监控与各项温度传感器

首先需要下载 OpenHardwareMonitorServer 这是一个基于OpenHardwareMonitor 的 Web 服务器。可以让任何语言都可以获取硬件信息和值&#xff0c;OpenHardwareMonitorServer 是没有UI界面的因此它可以当成控制台程序使用。 该程序可用参数如下 参数&#xff1a;需要管理员权限…

解锁大语言模型潜能:KITE 提示词框架全解析

大语言模型的应用日益广泛。然而&#xff0c;如何确保这些模型生成的内容在AI原生应用中符合预期&#xff0c;仍是一个需要不断探索的问题。以下内容来自于《AI 原生应用开发&#xff1a;提示工程原理与实战》一书&#xff08;京东图书&#xff1a;https://item.jd.com/1013604…

C++STL容器之map的使用及复现

map 1. 关联式容器 vector、list、deque、forward_list(C11) 等STL容器&#xff0c;其底层为线性序列的数据结构&#xff0c;里面存储的是元素本身&#xff0c;这样的容器被统称为序列式容器。而 map、set 是一种关联式容器&#xff0c;关联式容器也是用来存储数据的&#xf…

网络工程师 (30)以太网技术

一、起源与发展 以太网技术起源于20世纪70年代&#xff0c;最初由Xerox公司的帕洛阿尔托研究中心&#xff08;PARC&#xff09;开发。最初的以太网采用同轴电缆作为传输介质&#xff0c;数据传输速率为2.94Mbps&#xff08;后发展为10Mbps&#xff09;&#xff0c;主要用于解决…

30天开发操作系统 第 20 天 -- API

前言 大家早上好&#xff0c;今天我们继续努力哦。 昨天我们已经实现了应用程序的运行, 今天我们来实现由应用程序对操作系统功能的调用(即API, 也叫系统调用)。 为什么这样的功能称为“系统调用”(system call)呢&#xff1f;因为它是由应用程序来调用(操作)系统中的功能来完…

Java面试题及答案整理( 2023年 6 月最新版,持续更新)

秋招金九银十快到了&#xff0c;发现网上很多Java面试题都没有答案&#xff0c;所以花了很长时间搜集整理出来了这套Java面试题大全~ 这套互联网 Java 工程师面试题包括了&#xff1a;MyBatis、ZK、Dubbo、EL、Redis、MySQL、并发编程、Java面试、Spring、微服务、Linux、Spri…

查询语句来提取 detail 字段中包含 xxx 的 URL 里的 commodity/ 后面的数字串

您可以使用以下 SQL 查询语句来提取 detail 字段中包含 oss.kxlist.com 的 URL 里的 commodity/ 后面的数字串&#xff1a; <p><img style"max-width:100%;" src"https://oss.kxlist.com//8a989a0c55e4a7900155e7fd7971000b/commodity/20170925/20170…

管式超滤膜分离技术都可以应用到哪些行业?

管式超滤膜分离技术由于其高效、稳定和适应性强的特点&#xff0c;在多个行业都有广泛的应用&#xff1a; 1. 生物制药与医药行业 纯化与浓缩&#xff1a;在生物药品的下游处理阶段&#xff0c;管式超滤膜被用来纯化抗体、疫苗、蛋白质等生物大分子&#xff0c;通过精确筛选分子…

基于opencv的 24色卡IQA评测算法源码-可完全替代Imatest

1.概要 利用24色卡可以很快的分析到曝光误差&#xff0c;白平衡误差&#xff0c;噪声&#xff0c;色差&#xff0c;饱和度&#xff0c;gamma值。IQA或tuning工程一般用Imatest来手动计算&#xff0c;不便于产测部署&#xff0c;现利用opencv实现了imatest的全部功能&#xff0c…

【matlab优化算法-17期】基于DBO算法的微电网多目标优化调度

基于蜣螂DBO算法的微电网多目标优化调度 一、前言 微电网作为智能电网的重要组成部分&#xff0c;其优化调度对于降低能耗、减少环境污染具有重要意义。本文介绍了一个基于Dung Beetle Optimizer&#xff08;DBO&#xff09;算法的微电网多目标优化调度项目&#xff0c;旨在通…

【多模态大模型】系列2:Transformer Encoder-Decoder——BLIP、CoCa、BEITv3

目录 1 BLIP2 CoCa3 BEITv3 1 BLIP BLIP: Bootstrapping Language-Image Pre-training for Unified Vision-Language Understanding and Generation BLIP是 ALBEF 原班人马做的&#xff0c;基本可以看做吸收了 VLMo 思想的 ALBEF。训练的 loss 和技巧都与 ALBEF一致&#xff…

算法——搜索算法:原理、类型与实战应用

搜索算法&#xff1a;开启高效信息检索的钥匙 在信息爆炸的时代&#xff0c;搜索算法无疑是计算机科学领域中熠熠生辉的存在&#xff0c;它就像一把神奇的钥匙&#xff0c;为我们打开了高效信息检索的大门。无论是在日常生活中&#xff0c;还是在专业的工作场景里&#xff0c;…

在vmd中如何渲染透明水分子

1.设置背景为白色 依次点击Graphics>>Colors... 2. 改变渲染模式 依次点击Display>>rendermode>>GLSL 3. 渲染水分子 选中水分子&#xff0c;显色方式改为ColorID, 编号10的颜色&#xff1b; 选择材质为GlassBubble; 绘图方式为QuickSurf. 若水盒子显示效…

【Cocos TypeScript 零基础 15.1】

目录 见缝插针UI脚本针脚本球脚本心得_旋转心得_更改父节点心得_缓动动画成品展示图 见缝插针 本人只是看了老师的大纲,中途不明白不会的时候再去看的视频 所以代码可能与老师代码有出入 SIKI_学院_点击跳转 UI脚本 import { _decorator, Camera, color, Component, directo…

Go+Wails+Vue 开发:添加停止按钮功能的实现

在本教程中&#xff0c;我将展示如何在一个使用 Wails 框架&#xff08;后端 Go&#xff09;和 Vue.js&#xff08;前端&#xff09;的彩票模拟器项目中添加一个“停止”按钮。由于现有的教程内容较为单一&#xff0c;我将通过具体的实现步骤进行详细说明。 项目初始化 首先&a…

微服务保护---Sentinel

1. 初始Sentinel 1.1. 雪崩问题及解决方案 1.1.1. 雪崩问题 微服务中&#xff0c;服务间调用关系错综复杂&#xff0c;一个微服务往往依赖于多个其它微服务。 如图&#xff0c;如果服务提供者I发生了故障&#xff0c;当前的应用的部分业务因为依赖于服务I&#xff0c;因此也会…

win32汇编环境,窗口程序使用跟踪条(滑块)控件示例一

;运行效果 ;win32汇编环境,窗口程序使用跟踪条(滑块)控件示例一 ;生成2条横的跟踪条,分别设置不同的数值范围,设置不同的进度副度的例子 ;直接抄进RadAsm可编译运行。重要部分加备注。 ;下面为asm文件 ;>>>>>>>>>>>>>>>>>…