实现 getType 数据类型检测

手写 getType 函数获取 JavaScript 详细数据类型

问题

实现一个 getType 函数,能够准确返回任意值的详细数据类型。

typeof 的局限性:

typeof null        // 'object' ❌
typeof []          // 'object' ❌
typeof {}          // 'object'
typeof new Date()  // 'object' ❌

解答

基础实现

function getType(value) {
  // Object.prototype.toString.call() 返回 '[object Type]' 格式
  const type = Object.prototype.toString.call(value)
  // 提取 Type 部分并转为小写
  return type.slice(8, -1).toLowerCase()
}

测试用例

// 基本类型
getType(123)           // 'number'
getType('hello')       // '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(/abc/)         // 'regexp'
getType(new Map())     // 'map'
getType(new Set())     // 'set'
getType(new WeakMap()) // 'weakmap'
getType(new WeakSet()) // 'weakset'
getType(Promise.resolve()) // 'promise'
getType(new Error())   // 'error'

带类型判断的工具函数

const typeUtils = {
  getType(value) {
    return Object.prototype.toString.call(value).slice(8, -1).toLowerCase()
  },
  
  isArray(value) {
    return this.getType(value) === 'array'
  },
  
  isObject(value) {
    return this.getType(value) === 'object'
  },
  
  isFunction(value) {
    return this.getType(value) === 'function'
  },
  
  isNull(value) {
    return this.getType(value) === 'null'
  },
  
  isUndefined(value) {
    return this.getType(value) === 'undefined'
  },
  
  // 判断是否为原始类型
  isPrimitive(value) {
    return value === null || !['object', 'function'].includes(typeof value)
  }
}

关键点

  • Object.prototype.toString.call() 是最可靠的类型检测方法
  • 返回格式为 [object Type],需要用 slice(8, -1) 提取类型名
  • typeof null 返回 'object' 是 JavaScript 的历史 bug
  • Array.isArray() 是判断数组的推荐方法,但 getType 更通用
  • 该方法可以区分 DateRegExpMapSet 等内置对象类型