typeof 是用来获取一个JavaScript数据类型的操作符,但是有经验的开发者都知道typeof在某些情况下是无法返回数据精确类型的,比如
document.write(typeof []);
返回的并不是 array ,而是object,所以是无法通过typeof分辨 [] 和 {} 的类型的,那么有解决方案吗?先上代码
var toType=function (obj){
return Object.prototype.toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase();
}
接下来,来解释一下上面的代码
toString
toString()是核心,该方法返回 [object type] 其中type 就是对象的类型
但是默认情况下,toString()方法会被每个Object重写,比如数组的toString就被重写成了
document.write([1,2,3].toString()); //1,2,3
所以为什么要用Object 原型上的toString()?就是为了避免使用到被重写的toString()方法,当然你也可以用一个新的自定义的对象,他的toString()方法是没有被重写的
document.write(({}).toString()); //[object Object]
注意,由于{}的特殊性,这里的{}必须加上小括号,
Object.prototype.toString.call(obj) 作用在各种数据类型的结果如下:
Object.prototype.toString.call(null)
"[object Null]"
Object.prototype.toString.call(undefined)
"[object Undefined]"
Object.prototype.toString.call('hello')
"[object String]"
Object.prototype.toString.call({})
"[object Object]"
Object.prototype.toString.call([])
"[object Array]"
Object.prototype.toString.call(10)
"[object Number]"
Object.prototype.toString.call(true)
"[object Boolean]"
Object.prototype.toString.call(function(){})
"[object Function]"
Object.prototype.toString.call(new Date())
"[object Date]"
Object.prototype.toString.call(/\s/)
"[object RegExp]"
可以发现我们想要的数据精确类型结果都可以通过 toString 来获得。
提取
拿到toString()的结果后,就该提取具体的类型值了,比如数组的 [object Array] 方法有很多,对于诸如此类的字符串提取,正则表达式绝对是一个好选择,这里我们用到了字符串的 match 方法
"[object Array]".match(/\s([a-zA-Z]+)/)
实际上就是匹配以空格开始(\s)的字符串,注意这里的括号,这回作为match方法返回数组中的一项,可以直接拿到不带空格的结果值,如果不加括号就会发现只有一个带空格的Array,完事还得处理,最后就是拿到索引为1的结果,有需要再用到toLowerCase()转为小写
总结
toString()方法是获取数据精确类型的核心,可以用
Object.prototype.toString.call(obj)
也可以用
({}).toString.call(obj)