【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的指向。

结束

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

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

相关推荐
GIS程序媛—椰子15 分钟前
【Vue 全家桶】7、Vue UI组件库(更新中)
前端·vue.js
DogEgg_00121 分钟前
前端八股文(一)HTML 持续更新中。。。
前端·html
ZL不懂前端24 分钟前
Content Security Policy (CSP)
前端·javascript·面试
木舟100928 分钟前
ffmpeg重复回听音频流,时长叠加问题
前端
王大锤439138 分钟前
golang通用后台管理系统07(后台与若依前端对接)
开发语言·前端·golang
我血条子呢1 小时前
[Vue]防止路由重复跳转
前端·javascript·vue.js
黎金安1 小时前
前端第二次作业
前端·css·css3
啦啦右一1 小时前
前端 | MYTED单篇TED词汇学习功能优化
前端·学习
半开半落1 小时前
nuxt3安装pinia报错500[vite-node] [ERR_LOAD_URL]问题解决
前端·javascript·vue.js·nuxt