【js 类型检测】的基础类型,引用类型的类型检测

类型检测

前言:

js的类型检测是老生常谈的一个点,那为什么还要写这篇文章呢?

这个点不管在面试还是知识储备都是要会的。

所以这篇文章算是自己的一个记录,如果顺便能对你有点帮助的话,那我感到很荣幸!!!!

嘻嘻嘻嘻嘻,有不对的地方请都多指教,作出修改

进入正题

typeof

(返回值是字符串类型哦,连用 typeof typeof 111 ==> string )

对外称:只能检测基本数据类型。

是这样没错,但是往往别人问了,不只是要你这个回答。

先让我们 look look,基本返回的值。

类型 结果
Undefined "undefined"
Null "object"原因
Boolean "boolean"
Number "number"
BigInt "bigint"
String "string"
Symbol "symbol"
Function(在 ECMA-262 中实现 \[Call];classes也是函数) "function"
其他任何对象 "object"

上面的链接点击会跳转 MDN,有小伙伴需要更加详细的解释,或者知道其他的信息,可以点击跳转

那我就先说说我的:

  1. 有一个例外是检测基本类型null的时候,返回的不是预计的代表null类型的字符串,

    而是object。

    在JS的最初版本中使用的是32位系统,为了性能考虑使用低位存储变量的类型信息,

    000开头的是对象,null是全0,所以将null误判为Object了。

    虽然现在的内部类型判断代码已经改变了,但bug永久的遗留下来了。

  2. typeof判断对象,除了function都会显示object,所以typeof并不能准确地判断变量类型.

  3. 局限性以及一些例外

  • 数组和 nulltypeof 对于数组会返回 "object",而不是 "array";对于 null 也会返回 "object",这是 JavaScript 语言本身的历史遗留问题。
  • 对象内部的具体类型typeof 无法区分对象内部的具体类型,它会将所有对象的内部类型都归为 "object"
  • NaN 检测typeof NaN 会返回 "number",这是因为 NaN 是一种特殊的数值。
  • 函数内部的具体类型typeof 无法区分不同类型的函数,它会将所有函数都归为 "function"
  • 无法检测引用类型的具体类型typeof 无法检测出引用类型(对象、数组、函数等)的具体类型,比如无法区分一个对象是普通对象还是数组对象。
  • 举个例子,假设我们有一个变量 arr,它存储着一个数组对象:
ini 复制代码
var arr = [1, 2, 3];

如果我们使用 typeofarr 进行检测:

javascript 复制代码
console.log(typeof arr); // 输出 "object"

同样地,对于普通的对象也是一样的情况:

ini 复制代码
var obj = { name: "John", age: 25 };
console.log(typeof obj); // 输出 "object"

这意味着当我们使用 typeof 操作符来检测引用类型时,无法得知它们具体属于哪种引用类型。这就是说,typeof 无法提供关于对象、数组、函数等引用类型的具体细分信息。

为了更准确地识别引用类型的具体类型,我们可以使用更为详细的方法,比如:

  • 使用 Array.isArray() 方法来检测一个对象是否为数组。
  • 使用 Object.prototype.toString.call() 方法来获取对象的精确类型信息。

instanceof

上面不是说了typeof,那接下来就是他的好兄弟 instanceof。
instanceof 运算符的原理是基于对象的原型链进行检查。它用于确定一个对象是否属于特定类型或该类型的子类。

当使用 instanceof 运算符时,它会检查对象的原型链上是否存在该类型的原型。如果存在,则返回 true,否则返回 false

下面是 instanceof 运算符的工作原理的一般步骤:

  1. 检查对象的原型链中的每个原型是否与指定的构造函数的原型相等。
  2. 如果在原型链中找到匹配的原型,返回 true
  3. 如果在整个原型链上都没有找到匹配的原型,返回 false

让我们通过一个示例来说明原理:

javascript 复制代码
javascriptCopy Code
function Animal() {}
function Dog() {}

Dog.prototype = Object.create(Animal.prototype);

var myDog = new Dog();

console.log(myDog instanceof Dog); // 输出 true
console.log(myDog instanceof Animal); // 输出 true

在这个例子中,我们创建了两个构造函数 AnimalDog。然后,我们将 Dog 的原型设置为 Animal 的实例,这样 Dog 继承了 Animal 的属性和方法。

接着,我们使用 new 关键字创建了一个 myDog 对象,它是 Dog 类型的实例。

最后,我们使用 instanceof 运算符检查 myDog 是否是 Dog 类型的实例,以及是否是 Animal 类型的实例。由于 Dog 的原型链中存在 Animal 的原型,所以两个检查都返回了 true

需要注意的是:

  • instanceof 运算符不会检查对象的构造函数,而是检查构造函数的原型。
  • 如果 constructor 属性被重写或更改,instanceof 可能会给出错误的结果。

总结起来,instanceof 运算符通过检查对象的原型链确定对象是否属于指定类型或其子类。它是基于原型继承机制的一种类型判断方法。

两者都可以检测的(object.prototype.tostring.call())

1.我相信大多数人对这个方法有一个误区。

包括我,在刚开始学JS的时候,容易对这个方法产生了一个错误的认知。

比如 const a = {name:"韩振方"},好像觉得 a.toString 方法应该返回字符串类型的{name:"韩振方"}

问题的关键点就恰恰在这个地方。

2.首先我们要知道 toString 这个方法,这个函数的返回值本来就应该是下面的固定格式。

一个字符串个格式的 [object xxxx]xxxx 代表着调用这个方法的"数据"的数据类型。

3.重点来了:

js其实是重写了某些数据类型的toString方法,所以才会造成下面的情况,在这里我们拿函数类型举例子,其他数据类型同理:

嗯...对,这才是我理想中的toString,会返回这个变量的字符串显示样子。

4.要想搞明白这个知识点,在这里你必须要对原型链和原型有清晰的认识。我们知道,JS的大原型其实是Object构造函数的prototype指向的那个Object,JS的世界的来源就是它。

这个对象上的toString方法才是原汁原味的toString。

5.当我们用delete方法去删除Function.prototype(也就是Function构造函数的原型)身上的toString,然后我们再次调用name.toString会发生什么呢?

6.但是我们往往不会用delete去删除,所以就采用call方法去改变Object.prototype.toString方法this的指向。

结束

这篇文字只是当一个记录作用,如果有错误的可以指教一下我更改。

还有其他检测类型的方法的,现在只是粗略记录,持续更新~~~~~~~

相关推荐
观无28 分钟前
若依EasyExcel实现单元格合并
开发语言·前端·javascript
愚公搬代码1 小时前
【愚公系列】《Web应用安全》001-VMware的安装
前端·安全
xiaohaiAIgeo1 小时前
【2026年】HG/T 20656-2024化工暖通空调设计规范:新版标准的变化与影响
java·前端·javascript·科普知识
立少→万能汉编1 小时前
用“立少→超文本”写静态网页,标签<倍>
服务器·前端·javascript
weixin_431600441 小时前
NestJS 入门(7):生命周期钩子——构造函数和 `OnModuleInit` 差在哪?
前端·后端·学习·node.js·nest.js
你挚爱的强哥2 小时前
【chromeDownload】自定义组件:多用于登录框底部提供下载Chrome谷歌浏览器的链接
前端·vue.js·chrome
cindershade2 小时前
用原生 HTML5 视频与 Canvas 实现浏览器端视频抽帧封面
前端
笨鸟先飞,勤能补拙2 小时前
Web 服务器与计算机网络全景原理
运维·服务器·前端·网络·人工智能·计算机网络·web安全
NutShell Wang2 小时前
Wails v3 Beta 实战:用显式对象模型重写你的第一个 Go 桌面应用
前端·人工智能·go·vibe coding
cindershade2 小时前
前端国际化工程实践:语言包拆分、动态加载与日期数字格式统一
前端