JavaScript 中四种常见的数据类型判断方法

引言

JS 编程中, 正确判断数据类型是必备技能, 也是面试常问的内容。本文将探讨 四种 常用的数据类型判断方法:

  1. typeof

  2. instanceof & isPrototypeOf()

  3. constructor

  4. Object.prototype.toString.call()

通过了解它们的特点和适用范围, 能够更好地处理不同数据类型的情况, 避免出现错误和提升代码质量

一、typeof

typeof 运算符返回一个字符串, 表示操作数的类型, 使用语法: typeof <操作数>

1.1 规则

下表, 是 typeof 针对不同数据类型, 返回的结果值

类型结果
Boolean"boolean"
String"string"
Number"number"
BigInt"bigint"
Symbol"symbol"
Undefined"undefined"
Null"object"
Function (在 class 也是函数)"function"
其他任何对象"object"

示例代码如下:

console.log(typeof true) 
console.log(typeof '123') 

console.log(typeof 11111) 
console.log(typeof Math.LN2) 
console.log(typeof Infinity) 
console.log(typeof NaN) 

console.log(typeof BigInt(11111)) 
console.log(typeof Symbol(1111)) 
console.log(typeof undefined) 
console.log(typeof null) 

console.log(typeof (() => {})) 
console.log(typeof class {}) 

console.log(typeof {}) 
console.log(typeof []) 
console.log(typeof /abc/) 
console.log(typeof new Date()) 
console.log(typeof new Promise(() => {})) 

1.2 为什么「typeof null」等于「object」

typeof null === "object";

  1. JStypeof null 的结果为 "object", 这是从 JS 的第一版遗留至今的一个 bug

  2. JS 最初的实现中, JS 中的值是由一个表示类型的 标签实际数据值 表示的, 对象的 类型标签0, 由于 null 代表的是空指针, 在大多数平台下值表示为 0x00, 因此, null类型标签0, 因此 typeof null 也就返回了 object

  3. 当然针对这个 BUG 曾有一个 ECMAScript 的修复提案, 但是被拒绝了, 原因是遗留代码太多了, 如果修改的话影响太广, 不如继续将错就错当个和事老

1.3 为什么「typeof (() => {})」等于 「function」

首先我们需要了解一个小知识, 函数是什么? 为什么被调用?

function 实际上是 object 的一个 子类型, 更深点说, 函数是一个可以被调用的对象; 那么它为什么能够被调用呢? 那是因为其内部实现了 [[Call]] 方法, 当函数对象被调用时会执行内部方法 [[call]]

那么回到正题, 为什么 typeof (() => {}) 会返回 function? 这里主要还是要看 ES6typeof 是如何区分函数和对象类型的:

  • 一个对象如果没有实现 [[Call]] 内部方法, 那么它就返回 object

  • 一个对象如果实现了 [[Call]] 内部方法, 那么它就返回 function

1.4 注意事项

  1. 所有使用 构造函数 创建的数据, typeof 都会返回 objectfunction

const str = new String("String");
const num = new Number(100);

typeof str; 
typeof num; 

const func = new Function();

typeof func; 

  1. typeof 操作符的优先级高于 加法 (+)二进制操作符, 因此, 必要时候记得用括号

const someData = 99;

typeof someData + " Wisen"; 
typeof (someData + " Wisen"); 

二、instanceof & isPrototypeOf()

JS 中我们有 两种 方式可以判断 原型 是否存在于某个 实例原型链 上, 通过这种判断就可以帮助我们, 确定 引用数据 的具体类型; 需要注意的是该方法 只能用于判断引用数据, 无法判断 基本数据 类型

2.1 instanceof

  1. 介绍: instanceof 运算符用于检测 构造函数prototype 属性是否出现在 某个实例 对象的 原型链

  2. 语法: 实例对象 instanceof 构造函数, 返回一个 Boolean

  3. 示例:

function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}

const auto = new Car('Honda', 'Accord', 1998);

auto instanceof Car 
auto instanceof Object 

2.2 Object.prototype.isPrototypeOf()

  1. 介绍: isPrototypeOf() 方法用于检查一个 对象 是否存在于 另一个对象 的原型链中

  2. 语法: 原型.isPrototypeOf(实例), 返回一个布尔值

  3. 示例:

function Car() {}

const auto = new Car();

Car.prototype.isPrototypeOf(auto) 
Object.prototype.isPrototypeOf(auto) 

三、根据「constructor」进行判断

constructor 判断方法跟 instanceof 相似, 如下图是 原型实例构造函数 之间的一个关系图, 从图可知, 在 实例对象的原型 中存在 constructor 指向 构造函数, 那么借用这个特性我们可以用于判断 数据 类型

function Car() {}

const auto = new Car();

auto.constructor === Car 

不同于 instanceof, 通过该方式既可以处理 引用数据、又能够处理 基本数据

(123).constructor === Number 
(true).constructor === Boolean 
('bar').constructor === String 

不同于 instanceof, 不能判断 对象父类

class A {}

class B extends A {}

const b = new B()

b.constructor === B 
b.constructor === A 

b instanceof B 
b instanceof A 

注意: nullundefined 没有 constructor, 所以它是无法检测 Null undefined

四、Object.prototype.toString.call()

Object.prototype.toString.call() 方法返回一个表示该对象的字符串, 该字符串格式为 "[object Type]", 这里的 Type 就是对象的类型

const toString = Object.prototype.toString;

toString.call(111); 
toString.call(null); 
toString.call(undefined); 

toString.call(Math); 
toString.call(new Date()); 
toString.call(new String()); 

注意: 对于自定义构造函数实例化出来的对象, 返回的是 [object Object]

const toString = Object.prototype.toString;
function Bar(){}

toString.call(new Bar()); 

默认, 如果一个对象有 Symbol.toStringTag 属性并且该属性值是个字符串, 那么这个属性值, 会被用作 Object.prototype.toString() 返回内容的 Type 值进行展示

const toString = Object.prototype.toString;

const obj = {
  [Symbol.toStringTag]: 'Bar'
}

toString.call(obj) 

补充: 一个通用方法, 一行代码获取 数据的类型

const getType = (data) => {
  return Object.prototype.toString.call(data)
    .slice(8, -1)
    .toLocaleLowerCase()
}

五、总结

判断方法基本类型引用类型父类nullundefined
typeof
instanceof & isPrototypeOf()
constructor
Object.prototype.toString.call()
  1. typeof 适合用于判断 基本类型, 特别的是: Null 会返回 objectFunction 返回 function、其余 引用类型 都返回 object

  2. instanceof & isPrototypeOf() 可以用于判断引用数据的类型, 同时可判断 对象父类

  3. constructor 可用于基本类型、引用类型, 但是不可判断 nullundefined, 并且无法判断 对象父类

  4. Object.prototype.toString.call() 万能方法, 对于 JS 中所有类型都能够识别出来, 唯一不足的可能是无法判断 对象父类(但是问题不大)

作者-墨渊君,欢迎关注!

so
  • 结尾依旧:长风破浪会有时,直挂云帆济沧海!

  • 在线整理的确实很好,对文章进行了一个汇总整理,在线备战面试、刷题指南,拿走不谢,要学会站在别人的肩膀上提升自己点击这里-->

最后:

如果你现在正在找工作,可以私信“web”或者直接添加下方小助理进群领取前端面试小册、简历优化修改、大厂内推以及更多阿里、字节大厂面试真题合集,和p8大佬一起交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Web面试那些事儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值