Skip to content

变量和类型 - 判断JavaScript数据类型 #14

@logan70

Description

@logan70

判断JavaScript数据类型

实现判断数据类型功能

function getType(v) {
  // `null`
  if (v === null) return 'null'
  
  const baseType = typeof v
  // `undefined`、`number`、`string`、`boolean`、`symbol`、`bigInt`、`function`
  if (baseType !== 'object') return baseType

  // `arguments`、`error`、`date`、`regExp`、`object`
  // `map`、`set`、`weakmap`、`weakset`
  // 基本类型的包装类型按照其基本类型返回
  const builtinType = Object.prototype.toString.call(v)
    .slice(8, -1).toLocaleLowerCase()

  return builtinType
}

typeof

可判断类型UndefinedNumberStringBooleanSymbolBigIntFunction

坑点typeof null === 'object',JS历史Bug,修改后造成大量兼容问题,故遗留至今。

expect(typeof undefined).toBe('undefined')
expect(typeof 1).toBe('number')
expect(typeof 'Logan').toBe('string')
expect(typeof true).toBe('boolean')
expect(typeof Symbol()).toBe('symbol')
expect(typeof BigInt(123)).toBe('bigint')
expect(typeof (() => {})).toBe('function')

instanceof

instanceof 操作符左侧为引用类型,右侧为构造函数,作用是检测右侧构造函数的原型是否在左侧对象的原型链上出现过,故不太适合用作数据类型判断。

更多有关原型与原型链的内容,可前往 深入JavaScript系列(六):原型与原型链 了解。

expect([] instanceof Array).toBe(true)
expect([] instanceof Object).toBe(true)

expect(null instanceof Object).toBe(false)

Object.prototype.toString

由于基本类型的包装对象以及除Object外的其他引用类型大都重写了toString方法,导致我们无法得到预期的效果,故使用Object.prototype.toString,通过call调用将this指向我们想判断类型的变量或值。ECMAScript相关描述详见 ECMAScript#Object.prototype.toString

可以通过定义对象的[Symbol.toStringTag]属性来自定义Object.prototype.toString.call()时的表现,详见Symbol的应用及实现

将各个类型传入Object.prototype.toString.call()的表现如下表:

*Error代表所有错误类对象

传入变量类型 返回结果
Undefined '[object Undefined]'
Null '[object Null]'
Boolean '[object Boolean]'
Number '[object Number]'
String '[object String]'
Symbol '[object Symbol]'
BigInt '[object BigInt]'
Object '[object Object]'
Array '[object Array]'
Function '[object Function]'
Arguments '[object Arguments]'
Set '[object Set]'
Map '[object Map]'
WeakSet '[object WeakSet]'
WeakMap '[object WeakMap]'
Date '[object Date]'
RegExp '[object RegExp]'
*Error '[object Error]'

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions