javascript-理解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♪(・ω・)ノ。

猜你喜欢

转载自blog.csdn.net/harmsworth2016/article/details/83591506