在JS中有比typeof更好的方法来获取变量的类型吗?当你这样做时,它工作得很好:

> typeof 1
"number"
> typeof "hello"
"string"

但当你尝试的时候,它是无用的:

> typeof [1,2]
"object"
>r = new RegExp(/./)
/./
> typeof r
"function"

我知道instanceof,但这需要您事先知道类型。

> [1,2] instanceof Array
true
> r instanceof RegExp
true

有没有更好的办法?


当前回答

安格斯·克罗尔最近写了一篇有趣的博文

http://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/

他回顾了各种方法的优缺点,然后定义了一个新方法“toType”-

var toType = function(obj) {
  return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}

其他回答

这是一个更完整的版本:

const typeOf = obj => {
  let type = ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1]
  if (type === 'Object') {
    const results = (/^(function|class)\s+(\w+)/).exec(obj.constructor.toString())
    type = (results && results.length > 2) ? results[2] : ''
  }
  return type.toLowerCase()
}

现在你不仅可以得到这些结果:(就像这里回答的那样)

undefined or empty -> undefined
null -> null
NaN -> number
5 -> number
{} -> object
[] -> array
'' -> string
function () {} -> function
/a/ -> regexp
new Date() -> date
new Error -> error
Promise.resolve() -> promise
function *() {} -> generatorfunction
new WeakMap() -> weakmap
new Map() -> map

但你也可以从类或函数中获得你构造的每个实例或对象的类型:(在其他答案之间无效,它们都返回object)

class C {
  constructor() {
    this.a = 1
  }
}

function F() {
  this.b = 'Foad'
}

typeOf(new C()) // -> c
typeOf(new F()) // -> f

Typeof条件用于检查变量类型,如果你在if-else条件下检查变量类型 如。

if(typeof Varaible_Name "undefined")
{

}

一行函数:

function type(obj) {
    return Object.prototype.toString.call(obj).replace(/^\[object (.+)\]$/,"$1").toLowerCase()
}

这将得到与jQuery.type()相同的结果

我做了这个函数:

(您应该将其命名为更唯一的,这样它就不会与其他全局名称冲突。)

function type(theThing) {
    return Object.prototype.toString.call(theThing).match(/\s([\w]+)/)[1].toLowerCase()
}
type({})           //-> 'object'
type([])           //-> 'array'
type(function(){}) //-> 'function'
    
type(null)         //-> 'null'
type(undefined)    //-> 'undefined
type(true)         //-> 'boolean'
type('hello')      //-> 'string'
type(42)           //-> 'number'

type(Symbol())     //-> 'symbol'
type(/abc/)        //-> 'regexp'
type(new Set())    //-> 'set'
// etc ...

PS:上面的F.NiX做了更健壮的版本,它还告诉你从Class或构造函数中创建的自定义对象的名称。

您可以尝试使用constructor.name。

[].constructor.name
new RegExp().constructor.name

就像所有JavaScript一样,最终总会有人指出这在某种程度上是邪恶的,所以这里有一个链接,可以很好地回答这个问题。

另一种方法是使用Object.prototype.toString.call

Object.prototype.toString.call([])
Object.prototype.toString.call(/./)