龙空技术网

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

格子衬衫 208

前言:

现时朋友们对“js 数据类型判断”大体比较看重,你们都需要知道一些“js 数据类型判断”的相关内容。那么小编同时在网上搜集了一些关于“js 数据类型判断””的相关知识,希望看官们能喜欢,大家快快来学习一下吧!

引言

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

typeofinstanceof & isPrototypeOf()constructorObject.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) // booleanconsole.log(typeof '123') // stringconsole.log(typeof 11111) // numberconsole.log(typeof Math.LN2) // numberconsole.log(typeof Infinity) // numberconsole.log(typeof NaN) // numberconsole.log(typeof BigInt(11111)) // bigintconsole.log(typeof Symbol(1111)) // symbolconsole.log(typeof undefined) // undefinedconsole.log(typeof null) // objectconsole.log(typeof (() => {})) // functionconsole.log(typeof class {}) // functionconsole.log(typeof {}) // object console.log(typeof []) // objectconsole.log(typeof /abc/) // objectconsole.log(typeof new Date()) // objectconsole.log(typeof new Promise(() => {})) // object

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

// JavaScript 诞生以来便如此typeof null === "object";

在 JS 中 typeof null 的结果为 "object", 这是从 JS 的第一版遗留至今的一个 bug在 JS 最初的实现中, JS 中的值是由一个表示类型的 标签 和 实际数据值 表示的, 对象的 类型标签 是 0, 由于 null 代表的是空指针, 在大多数平台下值表示为 0x00, 因此, null 的 类型标签 是 0, 因此 typeof null 也就返回了 object当然针对这个 BUG 曾有一个 ECMAScript 的修复提案, 但是被拒绝了, 原因是遗留代码太多了, 如果修改的话影响太广, 不如继续将错就错当个和事老1.3 为什么「typeof (() => {})」等于 「function」

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

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

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

一个对象如果没有实现 [[Call]] 内部方法, 那么它就返回 object一个对象如果实现了 [[Call]] 内部方法, 那么它就返回 function1.4 注意事项所有使用 构造函数 创建的数据, typeof 都会返回 object 或 function

const str = new String("String");const num = new Number(100);typeof str; // "object"typeof num; // "object"const func = new Function();typeof func; // "function"

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

// 括号有无将决定表达式的类型。const someData = 99;typeof someData + " Wisen"; // "number Wisen"typeof (someData + " Wisen"); // "string"

二、instanceof & isPrototypeOf()

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

2.1 instanceof介绍: instanceof 运算符用于检测 构造函数 的 prototype 属性是否出现在 某个实例 对象的 原型链 上语法: 实例对象 instanceof 构造函数, 返回一个 Boolean 值示例:

function Car(make, model, year) {  this.make = make;  this.model = model;  this.year = year;}const auto = new Car('Honda', 'Accord', 1998);auto instanceof Car // Car.prototype 是否在 auto 原型链上, trueauto instanceof Object // Object.prototype 是否在 auto 原型链上, true

2.2 Object.prototype.isPrototypeOf()介绍: isPrototypeOf() 方法用于检查一个 对象 是否存在于 另一个对象 的原型链中语法: 原型.isPrototypeOf(实例), 返回一个布尔值示例:

function Car() {}const auto = new Car();Car.prototype.isPrototypeOf(auto) // Car.prototype 是否在 auto 原型链上, trueObject.prototype.isPrototypeOf(auto) // Object.prototype 是否在 auto 原型链上, true

关于原型、原型链更多知识可查阅 《原型、原型链》

三、根据「constructor」进行判断

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

function Car() {}const auto = new Car();auto.constructor === Car // true

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

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

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

class A {}class B extends A {}const b = new B()b.constructor === B // trueb.constructor === A // falseb instanceof B // trueb instanceof A // true

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

关于原型、原型链更多知识可查阅 《原型、原型链》

四、Object.prototype.toString.call()

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

const toString = Object.prototype.toString;toString.call(111); // [object Number]toString.call(null); // [object Null]toString.call(undefined); // [object Undefined]toString.call(Math); // [object Math]toString.call(new Date()); // [object Date]toString.call(new String()); // [object String]

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

const toString = Object.prototype.toString;function Bar(){}toString.call(new Bar()); // [object Object]

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

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

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

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

五、总结

判断方法

基本类型

引用类型

父类

null

undefined

typeof

instanceof & isPrototypeOf()

constructor

Object.prototype.toString.call()

typeof 适合用于判断 基本类型, 特别的是: Null 会返回 object、 Function 返回 function、其余 引用类型 都返回 objectinstanceof & isPrototypeOf() 可以用于判断引用数据的类型, 同时可判断 对象父类constructor 可用于基本类型、引用类型, 但是不可判断 null、undefined, 并且无法判断 对象父类Object.prototype.toString.call() 万能方法, 对于 JS 中所有类型都能够识别出来, 唯一不足的可能是无法判断 对象父类(但是问题不大)

作者:墨渊君

链接:

标签: #js 数据类型判断