JavaScript 中判断数据类型的方法

89 阅读2分钟

JavaScript 中判断数据类型的方法

JavaScript 的数据类型

JavaScript 中有 8 种数据类型:

  • 基本数据类型(原始类型):
    • Number(数字)
    • String(字符串)
    • Boolean(布尔值)
    • Null(空值)
    • Undefined(未定义)
    • Symbol(ES6 新增,符号)
    • BigInt(ES10 新增,大整数)
  • 引用数据类型:
    • Object(对象,包括普通对象 Object、数组 Array、函数 Function、日期 Date、正则 RegExp 等)

判断数据类型的方法

1. typeof 操作符

typeof 123; // "number"
typeof "abc"; // "string"
typeof true; // "boolean"
typeof undefined; // "undefined"
typeof Symbol(); // "symbol"
typeof 123n; // "bigint"
typeof {}; // "object"
typeof []; // "object"
typeof null; // "object" (这是一个历史遗留问题,实际上null不是对象)
typeof console.log; // "function"

特点

  • 简单易用,但对于引用类型的判断不够精确
  • 不能区分 Array、null 和普通 Object
  • 但能单独识别 Function 类型

2. instanceof 操作符

检测构造函数的 prototype 属性是否出现在对象的原型链中。

[] instanceof Array; // true
[] instanceof Object; // true (因为Array继承自Object)
new Date() instanceof Date; // true
/regex/ instanceof RegExp; // true
({}) instanceof Object; // true

特点

  • 适合用于检测引用类型
  • 考虑了原型链,所以会检测到继承关系
  • 无法正确判断基本数据类型,除非是通过构造函数创建的基本类型

3. Object.prototype.toString.call()

最准确的判断方法。

Object.prototype.toString.call(123); // "[object Number]"
Object.prototype.toString.call("abc"); // "[object String]"
Object.prototype.toString.call(true); // "[object Boolean]"
Object.prototype.toString.call(undefined); // "[object Undefined]"
Object.prototype.toString.call(null); // "[object Null]"
Object.prototype.toString.call(Symbol()); // "[object Symbol]"
Object.prototype.toString.call(123n); // "[object BigInt]"
Object.prototype.toString.call({}); // "[object Object]"
Object.prototype.toString.call([]); // "[object Array]"
Object.prototype.toString.call(function () {}); // "[object Function]"
Object.prototype.toString.call(new Date()); // "[object Date]"
Object.prototype.toString.call(/regex/); // "[object RegExp]"

特点

  • 最准确、全面的类型检测方法
  • 可以检测所有的数据类型,包括基本类型和引用类型
  • 返回格式为"[object Type]",需要处理字符串提取真正的类型

4. Array.isArray()

专门用于判断数组类型的方法。

Array.isArray([]); // true
Array.isArray({}); // false

特点

  • 专门用于检测数组类型
  • ES5 新增的方法,旧浏览器可能不支持

5. 构造函数名(constructor)

通过查看实例的 constructor 属性来判断类型。

(123).constructor === Number; // true
"abc".constructor === String; // true
true.constructor === Boolean; // true
({}).constructor === Object; // true
[].constructor === Array; // true
(function () {}).constructor === Function; // true

特点

  • 简单易用
  • 但 constructor 属性可以被修改,不够可靠
  • null 和 undefined 没有 constructor 属性

封装通用的类型判断函数

function getType(value) {
  // 处理null特殊情况
  if (value === null) {
    return "null";
  }

  // 处理基本类型和函数
  const typeOfResult = typeof value;
  if (typeOfResult !== "object") {
    return typeOfResult;
  }

  // 处理引用类型
  const objectTypeString = Object.prototype.toString.call(value);
  const type = objectTypeString.slice(8, -1).toLowerCase();
  return type;
}

// 使用示例
getType(123); // "number"
getType("abc"); // "string"
getType(true); // "boolean"
getType(undefined); // "undefined"
getType(null); // "null"
getType(Symbol()); // "symbol"
getType(123n); // "bigint"
getType({}); // "object"
getType([]); // "array"
getType(function () {}); // "function"
getType(new Date()); // "date"
getType(/regex/); // "regexp"

延伸问题

  1. typeof null 为什么会返回 "object"?
  2. instanceof 操作符的工作原理是什么?
  3. 如何可靠地检测数组类型?
  4. 如何区分普通对象和其他引用类型如数组、日期等?
  5. 实现一个通用的类型检测函数。