toString方法的妙处
toString方法是javascript的原生方法,每一种数据类型从Object继承了该方法,今天来说说toString方法的巧妙之处。
判断数据类型
日常开发时,经常需用到判断数据类型的时候,通常用到typeof或者instanceof这2个关键字。typeof将数据类型转成字符串表示,缺点是无法区分null和object类型。而且,instanceof将变量的构造函数与javascript提供的原生构造函数比较,返回布尔值,缺点是只能判断引用类型,且无法区分函数和对象。此时,就该toString方法大显神威了。
function isNumber(obj){
return toString.call(obj) === '[object Number]'
}
上面的写法看似没错,却存在一个隐藏的bug!
toString()方法是window对象的全局属性,而该属性是可以修改的,故存在出错的可能。若toString()方法未被重新赋值,在Chrome浏览器中不会报错,而IE11浏览器直接报错!
故上述方法需要改动。
function isNumber(obj){
return Object.prototype.toString.call(obj) === '[object Number]'
}
巧妙之处就是借用Object原型上的toString()方法,已知Object原型上的方法是无法修改的,故IE11浏览器就没报错了。
花样繁多的类型判断
方式一(原型的toString方法)
const types = ['Arguments', 'Function', 'Array', 'Object', 'String', 'Number', 'Date', 'RegExp', 'Error', 'Symbol', 'Map', 'WeakMap', 'Set', 'WeakSet']
const fns = {}
types.forEach(v => {
fns[`is${v}`] = obj => {
return Object.prototype.toString.call(obj) === `[object ${v}]`
}
})
export default {
...fns
}
方式二(es6提供的Reflect方法!推荐使用)
const types = ['Arguments', 'Function', 'Array', 'Object', 'String', 'Number', 'Date', 'RegExp', 'Error', 'Symbol', 'Map', 'WeakMap', 'Set', 'WeakSet']
const fns = {}
types.forEach(v => {
fns[`is${v}`] = obj => {
return Reflect.apply(Object.prototype.toString, obj, []) === `[object ${v}]`
}
})
export default {
...fns
}
总结
对toString()方法和判断数据类型的使用方式的一些浅显看法,如果不正之处,请指出,Thanks♪(・ω・)ノ。