在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
有没有更好的办法?
你可能会发现以下函数很有用:
function typeOf(obj) {
return {}.toString.call(obj).split(' ')[1].slice(0, -1).toLowerCase();
}
或者在ES7中(如果有进一步改进请评论)
const { toString } = Object.prototype;
function typeOf(obj) {
const stringified = obj::toString();
const type = stringified.split(' ')[1].slice(0, -1);
return type.toLowerCase();
}
结果:
typeOf(); //undefined
typeOf(null); //null
typeOf(NaN); //number
typeOf(5); //number
typeOf({}); //object
typeOf([]); //array
typeOf(''); //string
typeOf(function () {}); //function
typeOf(/a/) //regexp
typeOf(new Date()) //date
typeOf(new Error) //error
typeOf(Promise.resolve()) //promise
typeOf(function *() {}) //generatorfunction
typeOf(new WeakMap()) //weakmap
typeOf(new Map()) //map
typeOf(async function() {}) //asyncfunction
感谢@johnrees通知我:错误,承诺,生成器函数
我做了这个函数:
(您应该将其命名为更唯一的,这样它就不会与其他全局名称冲突。)
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或构造函数中创建的自定义对象的名称。
这是一个更完整的版本:
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
YUI3使用的是一个相当不错的类型捕获函数:
var TYPES = {
'undefined' : 'undefined',
'number' : 'number',
'boolean' : 'boolean',
'string' : 'string',
'[object Function]': 'function',
'[object RegExp]' : 'regexp',
'[object Array]' : 'array',
'[object Date]' : 'date',
'[object Error]' : 'error'
},
TOSTRING = Object.prototype.toString;
function type(o) {
return TYPES[typeof o] || TYPES[TOSTRING.call(o)] || (o ? 'object' : 'null');
};
这捕获了javascript提供的许多原语,但您总是可以通过修改TYPES对象添加更多原语。注意,Safari中的typeof HTMLElementCollection将报告function,而type(HTMLElementCollection)将返回object