进阶理解——typeof 、instanceof
typeof 、instance of
- 先聊聊JavaScript基本类型
- 数据类型
- 5种含值数据类型
- 2种不含值类型
- 6种类型的*对象*
- typeof
- instanceof
- 总结
- 进一步扩展一下
- 具体讨论一下typeof局限性
- 扩展判断方法
很多时候,回头望,理解会更深刻,也希望能帮助一些初学的同学理解。
先聊聊JavaScript基本类型
以下类型一定注意区别
数据类型
5种含值数据类型
在 JavaScript 中有 5 种不同的可以包含值的数据类型:
stringnumberbooleanobjectfunction
2种不含值类型
nullundefined
6种类型的对象
ObjectDateArrayStringNumberBoolean
typeof
您可以使用 typeof 运算符来确定 JavaScript 变量的数据类型,返回对应数据类型字符串。
这是官方的一句话,细品,这说明什么?
说明:我们可以通过这个运算符判断出含值和不含值的数据类型。
而类似于Array、Date等类型的对象,我们无法具体判断,只能判断出时一个object数据类型。
typeof "Bill" // 返回 "string"
typeof 3.14 // 返回 "number"
typeof NaN // 返回 "number"
typeof false // 返回 "boolean"
typeof [1,2,3,4] // 返回 "object"
typeof {name:'Bill', age:19} // 返回 "object"
typeof new Date() // 返回 "object"
typeof function () {} // 返回 "function"
typeof myCar // 返回 "undefined" *
typeof null // 返回 "object"
需要注意的是:
- NaN 的数据类型是数字
- 数组的数据类型是对象
- 日期的数据类型是对象
- null 的数据类型是 object
- 未定义变量的数据类型为 undefined *
- 未赋值的变量的数据类型也是 undefined *
看到这,心里可能会有疑惑,说好的可以判断数据类型,null为什么是object?
对咯。就他最特别,这实际上是语言设计上的一个错误,并且由于历史原因一直保留到了现在。所以他是特立独行的—一个bug。
原理是这样的,不同的对象在底层都表示为二进制,
在 JavaScript 中二进制前三位都为 0 的话会被判断为 object 类型,
null 的二进制表示是全 0,自然前三位也是 0,
所以执行 typeof 时会返回“object”。
想了解可以看看本链接
说到这里大家是不是明明白白了,除了一个bug null,typeof只能判断含值和不含值的数据类型。
像Array、Data等等这些对象的类型就无法具体判断了。
那么还有别的办法吗?
答案是肯定的
instanceof
instanceof 是一个二元运算符,用于测试构造函数的 prototype 属性是否出现在对象的原型链上。
如果对象是指定的构造函数创建的实例,或者继承自该构造函数的原型链,instanceof 运算符会返回 true。
class Car {}
const myCar = new Car();myCar instanceof Car // true
myCar instanceof Object // true(因为Car继承自Object)[] instanceof Array // true
([]) instanceof Object // true(因为所有的数组都是对象)function MyFunc() {}
const myFunc = new MyFunc();myFunc instanceof MyFunc // true
myFunc instanceof Object // true(因为所有函数都是对象)// 注意:字面量形式创建的基本类型不是任何构造函数的实例
'hello' instanceof String // false
42 instanceof Number // false
true instanceof Boolean // false
由于 instanceof 是基于原型链进行检查的,它能够用于检测复杂对象类型,比如自定义对象和内置对象实例(如 Array、Date 等)。然而,它不适用于基本数据类型。
总结
- 使用 typeof 来
检测基本数据类型,除了 null。 - 使用 instanceof 来
检查一个对象是否是某个特定类(或构造函数)的实例,或者说检测一个对象是否继承自某个原型。 - 要准确地判断一个变量是否为 null,应使用严格等于比较 (=== null)。
- 对于其他更复杂的类型检查需求,可能需要使用其他方法,比如 Object.prototype.toString.call(value)。
关于第三个,这里说一下undefined 与 null 的区别
undefined 和 null 值相等但类型不同:
typeof undefined // undefined
typeof null // objectnull === undefined // false
null == undefined // true
ps:如果有原型和原型链不太熟悉的,我会抽空补一篇,放下链接,还没有就说明还没写。。。
进一步扩展一下
具体讨论一下typeof局限性
typeof 运算符对于基本数据类型通常很有效,但在某些情况下,它并不能提供足够的信息来准确判断值的类型。以下是一些 typeof 无法准确检测的情况:
- 区分对象类型:typeof 将任何对象类型都返回为 “object”,不论它是一个普通的对象字面量、数组、正则表达式还是其他内置对象。
typeof []; // "object",但实际上是 Array
typeof {}; // "object",普通对象
typeof /regex/; // "object",在非标准的浏览器中可能返回 "function"
typeof new Date(); // "object",但实际上是 Date
- null 值:typeof null 返回 “object”,这实际上是一个长期存在的 JavaScript 错误。
typeof null; // "object",应该是 `null`
3.区分数组和普通对象:如上所述,数组和普通对象都返回 “object”。
typeof []; // "object",没有区分它是 Array
4.函数对象和普通对象:虽然 typeof 可以识别函数对象返回 “function”,但无法区分不同种类的函数(例如普通函数、箭头函数、异步函数、生成器函数等)。
typeof function(){}; // "function"
typeof (() => {}); // "function"
typeof async function(){}; // "function"
typeof function*(){}; // "function"
5.原始包装对象和原始值:对于字符串、数字和布尔值的原始包装对象,typeof 会将其视为 “object”,而非它们各自的原始类型。
typeof new String("string"); // "object"
typeof new Number(100); // "object"
typeof new Boolean(true); // "object"
6.特殊对象:typeof 对于特殊的对象,比如 Map、Set、WeakMap 和 WeakSet 等也只能返回 “object”。
typeof new Map(); // "object"
typeof new Set(); // "object"
- Undefined vs. undeclared:虽然 typeof 在处理未声明变量时不会抛出错误,并且会返回 “undefined”,但它无法区分一个变量是未定义还是未声明。
let x;
typeof x; // "undefined"
typeof y; // "undefined",即使 y 没有被声明
由于这些局限性,当需要更精确地判断复杂数据类型时,开发者通常会采用其他方法,如 instanceof 检查、Object.prototype.toString.call() 方法,或者在现代JavaScript框架和库中定义的自己的类型判断函数。
扩展判断方法
JavaScript 提供了 Array.isArray() 方法来特别判断一个值是否为数组。它比 typeof 更精确,因为 typeof 对于数组会返回 “object”。
对于其他类型的检查,虽然没有内置的类似 Array.isArray() 这样针对特定数据结构的方法,但我们可以使用 Object.prototype.toString.call() 来获取对象的类(class)信息:
let toString = Object.prototype.toString;// 使用 toString 方法检测不同类型
toString.call([]); // "[object Array]"
toString.call({}); // "[object Object]"
toString.call(''); // "[object String]"
toString.call(new Date()); // "[object Date]"
toString.call(1); // "[object Number]"
toString.call(true); // "[object Boolean]"
toString.call(function(){}); // "[object Function]"
toString.call(/regex/); // "[object RegExp]"
toString.call(null); // "[object Null]"
toString.call(undefined); // "[object Undefined]"
通过上面的方法,你可以构建自己的类型检查函数,就像 Array.isArray() 那样。例如:
function isDate(value) {return toString.call(value) === '[object Date]';
}
此外,ES6 引入了几个新的全局对象,也带来了类似的静态方法用于确定值是否为特定类型的实例:
- ArrayBuffer.isView(value): 检查一个值是否是类型化数组视图,比如 Int8Array 实例或其他类型化数组视图。
ArrayBuffer.isView(new Int8Array()); // true
ArrayBuffer.isView(new Float32Array()); // true
ArrayBuffer.isView([]); // false
- Number.isNaN(value): 确定传入的值是否是 NaN,且更准确地与全局 isNaN() 函数区分开来。
Number.isNaN(NaN); // true
Number.isNaN('NaN'); // false
- Number.isInteger(value): 判断给定的参数是否为整数。
Number.isInteger(1); // true
Number.isInteger(1.5); // false
- Number.isFinite(value): 检查一个值是否为有限数。
Number.isFinite(Infinity); // false
Number.isFinite(-Infinity); // false
Number.isFinite(1); // true
这些方法为不同类型的检测提供了官方支持并保证了结果的准确性。但仍然没有像 Array.isArray() 那样的方法用于直接检测 Map, Set, WeakMap, 或 WeakSet 等数据类型。在这些情况下,通常需要使用上述 Object.prototype.toString.call() 方式来进行类型的判断。
相关文章:
进阶理解——typeof 、instanceof
typeof 、instance of 先聊聊JavaScript基本类型数据类型5种含值数据类型2种不含值类型 6种类型的*对象* typeofinstanceof总结进一步扩展一下具体讨论一下typeof局限性扩展判断方法 很多时候,回头望,理解会更深刻,也希望能帮助一些初学的同学…...
不同类型的生物反应器在支架成熟过程中具有哪些特点和应用?
3D Bioprinting of Human Tissues: Biofabrication, Bioinks, and Bioreactors是发表于《International Journal of Molecular Sciences》的一篇综述,详细介绍了3D生物打印人体组织的相关技术进展,包括数据处理、生物打印技术、生物墨水配方、生物反应器…...
8. Spring Ai之入门到精通(超级详细)
简介 2024年5月30号Spring AI 的 1.0.0 里程碑 1 版本发布。表明版本已正在巩固,并且大部分主要错误和问题已经解决,API基本已确定,不会发生很大的变化。 在与大模型集成方面,继LangChain4j之后,又一重大的框架诞生。标…...
寄存器和硬件的关系
寄存器也是一种存储器,只不过普通的存储器只能写和读。里面的数据并没有赋予什么实际意义。但是寄存器就不一样了,寄存器的每一位数据,都对应了硬件电路的状态。寄存器和外设的硬件电路,是可以进行互动的。所以,程序到…...
【WEB】ctfshow-萌新-web9-15
文章目录 题目介绍:题目分析:payload: 题目介绍: ctfshow-萌新计划-web9-15 <?php # flag in config.php include("config.php"); if(isset($_GET[c])){$c $_GET[c];if(preg_match("/system|exec|highlight…...
【Vulnhub靶场AI-WEB-1.0打靶教程】
第一步:查看虚拟机的ip 第二步:扫描ip下开放的80端口 第三步:扫描查到的ip地址下的目录 第四步:访问查到的目录 访问robot.txt 第五步:访问robot.txt显示出的目录 第六步:打开kali终端,使用sqlmap功能 sq…...
html实现酷炫美观的可视化大屏(十种风格示例,附源码)
文章目录 完整效果演示1.蓝色流线风的可视化大屏1.1 大屏效果1.2 大屏代码1.3 大屏下载 2.地图模块风的可视化大屏2.1 大屏效果2.2 大屏代码2.3 大屏下载 3.科技轮动风的可视化大屏3.1 大屏效果3.2 大屏代码3.3 大屏下载 4.蓝色海洋风的可视化大屏4.1 大屏效果4.2 大屏代码4.3 …...
【C++BFS算法 二分查找】2812. 找出最安全路径
本文涉及知识点 CBFS算法 C二分查找 LeetCode2812. 找出最安全路径 给你一个下标从 0 开始、大小为 n x n 的二维矩阵 grid ,其中 (r, c) 表示: 如果 grid[r][c] 1 ,则表示一个存在小偷的单元格 如果 grid[r][c] 0 ,则表示一…...
轻触开关 KH-4.5X4.5X5.5H-STM
品 牌: kinghelm(金航标) 厂家型号: KH-4.5X4.5X5.5H-STM 封装: SMD 商品毛重: 0.317克(g) 包装方式: 编带...
3.redis客户端
1.命令行客户端 在安装redis的时候就已经安装好了,就是redis-cli redis-cli -h 127.0.0.1 -p 6379 -a 123456 -a 表示密码 -h 表示ip,不配置默认为本机 127.0.0.1 -p 表示端口,不配置默认为 6379 进入后可以输入ping,返回pong代表…...
Rust配置国内源,解决安装依赖慢问题
温馨提示:最新内容仅在原文更新。 国内源使用字节的RsProxy https://rsproxy.cn/ 解决rust-analyzer加载时间过长(请参考本文) 配置环境变量 Mac export RUSTUP_DIST_SERVER"https://rsproxy.cn" export RUSTUP_UPDATE_ROOT"https://rsproxy.cn/r…...
AI学习指南机器学习篇- Q学习的参数与调优
AI学习指南机器学习篇- Q学习的参数与调优 在强化学习领域中,Q学习是一种经典的算法,可以用来解决各种问题,包括游戏和机器人控制等。Q学习算法的性能很大程度上取决于一些重要的参数,例如学习率和折扣因子。本文将介绍这些参数的…...
《小迪安全》学习笔记02
域名默认存放目录和IP默认存放目录不一样。 IP地址是WWW文件里的,域名访问是WWW里的一个子目录里的(比如是blog)。 Nmap: Web源码拓展 拿到一个网站的源码,要分析这几个方面↑。 不同类型产生的漏洞类型也不一样 在网站中&…...
C语言:自定义类型进阶(结构体、联合体、枚举)
自定义类型(结构体、联合体、枚举) 一、结构体(一)结构体的内存对齐1、结构体内存对齐规则(1)引子(2)offsetof 宏函数(3)内存对齐原理(4ÿ…...
SPSSAU | 最好最差权重BWM原理及案例实操分析
BWM(best-worse-method,最好最差法)是一种多准则决策方法,由Jafar Rezaei于2015年提出,其通常用于确定决策标准的权重。其原理是比如5个指标,如果以前AHP就需要5个指标两两的相对重要性数据。但是现在简化为…...
docker安装elasticsearch(es)最新版本
docker安装elasticsearch(es) docker官网 https://hub.docker.com/ https://www.cnblogs.com/balloon72/p/13177872.html 1、拉取最新项目elasticsearch docker pull elasticsearch:8.14.3lscpu 查看架构 2、构建环境 mkdir -p /data/elasticsear…...
02 RabbitMQ:下载安装
02 RabbitMQ:下载&安装 1. 下载&安装1.1. 官网1.2. Docker方式1.2.1. 下载镜像1.2.2. 启动1.2.3. 登录验证 1. 下载&安装 1.1. 官网 RabbitMQ: One broker to queue them all | RabbitMQ 1.2. Docker方式 1.2.1. 下载镜像 # docker pull 镜像名称[…...
mmcv库出现No module named ‘mmcv._ext
遇到 "No module named mmcv._ext" 这个错误通常意味着你的 Python 环境中缺少 mmcv 库的扩展模块 _ext。mmcv(MMDetection 训练工具箱的核心库)通常依赖于 _ext 模块来提供一些高性能的操作,这些操作是用 C/C 实现的,并…...
防止xss(跨站脚本攻击)
1、输出数据时进行转义:这是最基本的预防措施。确保在输出数据到HTML时对特殊字符进行适当的转义,以防止它们被解释为HTML或JavaScript代码。PHP中可以使用htmlspecialchars()、strip_tags()、htmlentities函数来实现这一点。 echo htmlspecialchars($d…...
django小型超市库存与销售管理系统-计算机毕业设计源码46608
摘 要 随着信息技术的快速发展,超市库存与销售管理面临着前所未有的挑战与机遇。为了提升超市的运营效率,优化库存管理,并增强销售数据的分析能力,我们基于Django框架设计并开发了一套小型超市库存与销售管理系统。该系统充分利用…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...
STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
