javascript 判断类型的方法
在前端项目中,很多时候都要判断对象的类型,根据类型进一步再做处理。判断类型的方法上,有很多方式方法。本文进行依次讨论。
javascript 类型
首先要了解 javascript 的类型。类型分为基本类型和引用类型。
基本类型有:
string
、number
、boolean
、 null
、undefined
、symbol
ES6(2015) 新增、bigint
ES10(2019) 新增。
引用类型,常见有:
object
普通对象、array
数组、function
函数等。
typeof
最基础最简单莫过于 typeof
了,语法非常简单。 使用 typeof
可以返回以下结果:
const type = s => {
return typeof s
}
console.log(type('abc')) //=> string
console.log(type(123)) //=> number
console.log(type(NaN)) //=> number
console.log(type(BigInt(1))) //=> bigint
console.log(type(true)) //=> boolean
console.log(type(undefined)) //=> undefined
console.log(type(null)) //=> object
console.log(type(Symbol())) //=> symbol
console.log(type(function () {})) //=> function
console.log(type(class B extends A {})) //=> function
console.log(type(class A {})) //=> function
console.log(type([])) //=> object
console.log(type({ a: 1 })) //=> object
console.log(type(/a/g)) //=> object
console.log(type(document.createElement('div'))) //=> object
对于基本类型,除了 null
不可以判断外,其他都可以准确判断。当然,null
再稍微判断处理下也可以的。
下面实现了一个方法,可以准确判断出基本类型,对于引用类型,直接默认都是 object
:
const type = s => {
return s === null ? null : typeof s
}
constructor.name
通过构造器来判断类型,这个方案并不常用。因为对于基础类型 undefined
null
还不能直接判断。
不过好在对于一些原生的引用对象类型,可以区分出来。而且它还可以直接识别包装类型,比如 new Number(1)
,会认为是 Number
类型。
相应返回值参考如下:
const type = s => {
return s.constructor.name
}
console.log(type([]))
console.log(type('abc')) //=> String
console.log(type(123)) //=> Number
console.log(type(NaN)) //=> Number
console.log(type(BigInt(1))) //=> BigInt
console.log(type(true)) //=> Boolean
console.log(type(undefined)) //=> 报错
console.log(type(null)) //=> 报错
console.log(type(Symbol())) //=> Symbol
console.log(type(function () {})) //=> Function
console.log(type(class A {})) //=> Function
console.log(type(class B extends A {})) //=> Function
console.log(type([])) //=> Array
console.log(type({ a: 1 })) //=> Object
console.log(type(/a/g)) //=> RegExp
console.log(type(document.createElement('div'))) //=> HTMLDivElement
console.log(type(new Number(1))) //=> Number
除了判断 constructor.name
外,有的项目可能直接用 constructor
来实现:
const isNumber = s => {
return s.constructor === Number
}
console.log(isNumber(123)) //=> true
由于下面提到的 Object.prototype.toString.call
方法比这个更加稳定好用,所以我几乎没见项目使用过。
Object.prototype.toString.call
这个是项目上非常常用的判断方式,原生的类型不论是基础类型还是引用类型,都可以一步到位。
除非是对象继承没办法判断。而且它还可以直接识别包装类型,比如 new Number(1)
,会认为是 Number
类型。
const type = s => {
return Object.prototype.toString.call(s)
}
console.log(type('abc')) //=> [object String]
console.log(type(123)) //=> [object Number]
console.log(type(NaN)) //=> [object Number]
console.log(type(BigInt(1))) //=> [object BigInt]
console.log(type(true)) //=> [object Boolean]
console.log(type(undefined)) //=> [object Undefined]
console.log(type(null)) //=> [object Null]
console.log(type(Symbol())) //=> [object Symbol]
console.log(type(function () {})) //=> [object Function]
console.log(type(class A {})) //=> [object Function]
console.log(type(class B extends A {})) //=> [object Function]
console.log(type([])) //=> [object Array]
console.log(type({ a: 1 })) //=> [object Object]
console.log(type(/a/g)) //=> [object RegExp]
console.log(type(document.createElement('div'))) //=> [object HTMLDivElement]
console.log(type(new Number(1))) //=> [object Number]
Object.prototype.toString
经过查阅规范[1]可以返回如下类型:
[object Undefined]
[object Null]
[object Array]
[object String]
[object Arguments]
[object Function]
[object Error]
[object Boolean]
[object Number]
[object Date]
[object RegExp]
[object Object]
项目中,为了判断省事,常常会对返回值进行截取及大小写处理,一般为:
const type = s => {
return Object.prototype.toString.call(s).slice(8, -1).toLowerCase()
}
console.log(type('abc')) //=> string
此外,有的项目可能用 Reflect
来实现:
const type = s => {
return Reflect.apply(Object.prototype.toString, s, [])
}