JS数据类型判断总结

119 阅读2分钟

JavaScript 是一种弱类型(或称动态类型)语言,即变量的类型是不确定的。所以在特定场景下对数据类型的判断,就显得尤为重要,可保证我们程序的稳定性。

js中存在两类数据类型,基本数据类型引用数据类型

1. 基本数据类型

JavaScript有七种基本数据类型

  • number
  • string
  • boolean
  • symbol
  • bigint
  • undefined
  • null

2. 引用数据类型

除了上面的七种数据类型,其他的就是引用数据类型

  • Object
  • Array
  • Funciton
  • Date
  • RegExp
  • ...

3. 判断方法

有三种方法判断变量的数据类型

  • typeof
  • instanceof
  • Object.prototype.toString.call()

3.1 typeof

typeof主要用于基本数据类型的判断

typeof 1                // 'number'
typeof "1"              // 'string'
typeof true             // 'boolean'
typeof Symbol()         // 'symbol'
typeof 1n               // 'bigint'
typeof undefined        // 'undefined'
typeof null             // 'object'

typeof [] // 'object'
typeof {} // 'object'
typeof function() {}    // 'function'

可以看出typeof对于基本数据类型基本都可判断出来。null是个特例,可通过val === null进行判断。

typeof null === 'object'其实是js的一个bug,不代表null就是引用数据类型,并且null本身也不是对象)

原理:不同的对象在底层都表示为二进制,在Javascript中二进制前(低)三位存储其类型信息。

3.2 instanceof

instanceof主要用于引用数据类型的判断

({}) instanceof Object                          // true
([]) instanceof Array //或 Object               // true
(function(){}) instanceof Function //或 Object  // true
(/aa/g) instanceof RegExp                       // true
(new Date()) instanceof Date                    // true

let Person = function() {}
let jhon = new Person()
jhon instanceof Person                          // true
let newStr = new String('xxx')
newStr instanceof String                        // true
let str = 'xxx'
str instanceof String                           // false

可以看出instanceof对于引用数据类型基本都可判断出来。判断{}是个特例,可通过Object.prototype.toString.call(obj)==='[object Object]'进行判断。

(因为{}/[]/function instanceof Object都为true,所以Object并不能判断出该值的数据类型是{}。此外,对于基本数据类型的判断直接返回false)

原理instanceof 运算符检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上

3.3 Object.prototype.toString

通用的判断数据类型方法,调用该方法,统一返回[object Xxx]格式的字符串


Object.prototype.toString.call(1)             // "[object Number]"
Object.prototype.toString.call('1')           // "[object String]"
Object.prototype.toString.call(true)          // "[object Boolean]"
Object.prototype.toString.call(1n)            // "[object BigInt]"
Object.prototype.toString.call(Symbol())      // "[object Symbol]"
Object.prototype.toString.call(undefined)     //"[object Undefined]"
Object.prototype.toString.call(null)          //"[object Null]"

Object.prototype.toString.call({})            // "[object Object]"
Object.prototype.toString.call([])            //"[object Array]"
Object.prototype.toString.call(function(){})  // "[object Function]"

Object.prototype.toString.call(/123/g)        //"[object RegExp]"
Object.prototype.toString.call(new Date())    //"[object Date]"
Object.prototype.toString.call(document)      //"[object HTMLDocument]"
Object.prototype.toString.call(window)        //"[object Window]"

原理:获取this指向的那个对象的[[Class]]属性的值,返回[object className] 格式字符串

3.4 其他方法

constructor判断、Array.isArray()判断数组、Number.isNaN判断NaN,可作为判断补充

4. 总结

  1. typeof可判断大部分基本数据类型,基本数据类型null不可判断,引用数据类型function可判断。
  2. instanceof可判断大部分引用数据类型,{}不可判断。
  3. Object.prototype.toString可判断所有数据类型。

5. 封装通用类型判断工具

// @return
// number | string | boolean | bigint | symbol | undefined | null
// object | array | function | date | regexp | ...
function getTypeOf(val) {
  if (val === nullreturn "null";
  if (typeof val !== "object") { // 减少因tostring装箱操作,产生的临时对象
      return typeof val;
  } else {
      return Object.prototype.toString
      .call(val)
      .slice(8, -1)
      .toLocaleLowerCase();
  }
}

参考文档

  1. www.runoob.com/w3cnote/jav…
  2. cloud.tencent.com/developer/a…
  3. zhuanlan.zhihu.com/p/129642585
  4. juejin.cn/post/700030…
  5. juejin.cn/post/700965…