JavaScript 数据类型判断方法详解:typeof、instanceof、constructor 与 toString

作者:半夏时间:2026-10-30 20:43:14浏览:303

本文系统梳理 JavaScript 中四种常见的数据类型判断方法:typeof、instanceof、constructor 以及 Object.prototype.toString。详细解析了 typeof 返回 object 的历史原因、instanceof 的原型链检测机制、constructor 的局限性以及 toString 方法的通用性,并提供了各方法的适用场景与注意事项,帮助开发者根据实际需求选择最合适的类型检测方案。

一、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) // boolean
console.log(typeof '123') // string
console.log(typeof 11111) // number
console.log(typeof Math.LN2) // number
console.log(typeof Infinity) // number
console.log(typeof NaN) // number
console.log(typeof BigInt(11111)) // bigint
console.log(typeof Symbol(1111)) // symbol
console.log(typeof undefined) // undefined
console.log(typeof null) // object
console.log(typeof (() => {})) // function
console.log(typeof class {}) // function
console.log(typeof {}) // object 
console.log(typeof []) // object
console.log(typeof /abc/) // object
console.log(typeof new Date()) // object
console.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]] 内部方法,那么它就返回 function

1.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 原型链上, true
auto 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 原型链上, true
Object.prototype.isPrototypeOf(auto) // Object.prototype 是否在 auto 原型链上, true

三、根据「constructor」进行判断

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

一、typeof

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 // true
b.constructor === A // false
b instanceof B // true
b instanceof A // true

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

四、Object.prototype.toString.call()

Object.prototype.toString() 方法返回一个表示该对象的字符串,该字符串格式为 "[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(someType)
    .slice(8, -1)
    .toLocaleLowerCase()
}

五、总结

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

以上就是JavaScript中常见的数据类型判断方法小结的详细内容,更多关于JavaScript 判断方法的资料请关注本站其它相关文章!

作者最新文章