代码
let class2Type = {}
let dataType = ['Boolean', 'Number', 'String', 'Function',
'Array', 'Date', 'RegExp', 'Object', 'Error'
]
dataType.forEach((name, i) => {
class2Type['[object ' + name + ']'] = name.toLowerCase()
})
// 类型判断
function type(obj) {
if (obj === null || obj === undefined) {
return String(obj)
}
return typeof obj === 'object' || typeof obj === 'function' ?
class2Type[class2Type.toString.call(obj)] || 'object' :
typeof obj;
}
// 判断是不是函数
function isFunction(obj) {
return typeof obj === 'function'
}
// 判断是不是数组
function isArray(obj) {
if (Array.isArray) {
return Array.isArray(obj)
}
return type(obj) === 'array'
}
// 判断是不是window对象
function isWindow(obj) {
return obj !== null && obj !== undefined && obj === obj.window
}
// 判断是不是类数组
function isArrayLike(obj) {
let length = obj.length;
let type = type(obj)
return type === 'array' || type !== 'function' &&
(typeof length === 'number' && length > 0 && (length - 1) in obj)
}
说明
- 判断是否是数组,又新的原生方法
Array.isArray
, 这里兼容了低版本浏览器 window
对象有一个window
属性, 这个属性指向window
本身,即window.window === window
类型判断使用
typeof
是不可靠的,Value Class Type ------------------------------------- "foo" String string new String("foo") String object 1.2 Number number new Number(1.2) Number object true Boolean boolean new Boolean(true) Boolean object new Date() Date object new Error() Error object [1,2,3] Array object new Array(1, 2, 3) Array object new Function("") Function function /abc/g RegExp object (function in Nitro/V8) new RegExp("meow") RegExp object (function in Nitro/V8) {} Object object new Object() Object object
为了判断出类型,可以使用
Object.prototype.toString
方法获取对象的[[Class]]
值,Object.prototype.toString.call([]) // "[object Array]" Object.prototype.toString.call({}) // "[object Object]" Object.prototype.toString.call(2) // "[object Number]"
这样还不够,还需要单独处理
null
和undefined
。