1. 通过typeof检测
这是我们比较常用的一种类型检测方法,通过一段代码回顾下:
typeof 1 // number
typeof '1' // string
typeof undefined // undefined
typeof true // boolean
typeof Symbol() // symbol
typeof null // object
typeof [] // object
typeof {} // object
typeof console // object
typeof console.log // function
通过以上代码可以看出,typeof在判断null之前几个基本数据类型的时候基本上是准确无误的,可是在判断null时返回的是引用类型(object),这明显是有问题,null压根就不是引用类型,这是Js本身的一个bug,还有在判断数组类型、对象以及引用类型上都返回的是object,所以这也是有问题的,只有在判断function类型时是正确的!
以上这些坑在实际开发过程中应尽量避免!
2. 通过instanceof检测
想必 instanceof
的方法你也听说过,我们 new 一个对象,那么这个新对象就是它原型链继承上面的对象了,通过 instanceof 我们能判断这个对象是否是之前那个构造函数生成的对象,这样就基本可以判断出这个新对象的数据类型。下面通过代码来了解一下。
let Car = function() {}
let benz = new Car()
benz instanceof Car // true
let car = new String('Mercedes Benz')
car instanceof String // true
let str = 'Covid-19'
str instanceof String // false
那么typeof与instanceof之间有什么差异呢?
-
instanceof 可以准确地判断复杂引用数据类型,但是不能正确判断基础数据类型;
-
而 typeof 也存在弊端,它虽然可以判断基础数据类型(null 除外),但是引用数据类型中,除了 function 类型以外,其他的也无法判断。
总之,不管单独用 typeof 还是 instanceof,都不能满足所有场景的需求,而只能通过二者混写的方式来判断。但是,即使采用两种混写的方式,也只能检测大多数情况,并且写起来也相当难受!
所以,在实际开发中,推荐采用第三种判断方法!
3. 通过Object.prototype.toString检测
toString() 是 Object 的原型方法,调用该方法,可以统一返回格式为 “[object Xxx]” 的字符串,其中 Xxx 就是对象的类型。对于 Object 对象,直接调用 toString() 就能返回 [object Object]
;而对于其他对象,则需要通过 call 来调用,才能返回正确的类型信息。我们来看一下代码。
Object.prototype.toString({}) // "[object Object]"
Object.prototype.toString.call({}) // 同上结果,加上call也ok
Object.prototype.toString.call(1) // "[object Number]"
Object.prototype.toString.call('1') // "[object String]"
Object.prototype.toString.call(true) // "[object Boolean]"
Object.prototype.toString.call(function(){}) // "[object Function]"
Object.prototype.toString.call(null) //"[object Null]"
Object.prototype.toString.call(undefined) //"[object Undefined]"
Object.prototype.toString.call(/123/g) //"[object RegExp]"
Object.prototype.toString.call(new Date()) //"[object Date]"
Object.prototype.toString.call([]) //"[object Array]"
Object.prototype.toString.call(document) //"[object HTMLDocument]"
Object.prototype.toString.call(window) //"[object Window]"
从上面这段代码可以看出,Object.prototype.toString.call() 可以很好地判断引用类型,甚至可以把 document 和 window 都区分开来。
但是在写判断条件的时候一定要注意,使用这个方法最后返回统一字符串格式为 "[object Xxx]
" ,而这里字符串里面的 "Xxx" ,第一个首字母要大写(注意:使用 typeof 返回的是小写),这里需要多加留意。
那么下面来实现一个全局通用的数据类型判断方法,来加深理解,代码如下。
function getType(obj){
let type = typeof obj;
if (type !== "object") { // 先进行typeof判断,如果是基础数据类型,直接返回
return type;
}
// 对于typeof返回结果是object的,再进行如下的判断,正则返回结果
return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/, '$1'); // 注意正则中间有个空格
}
/* 代码验证,需要注意大小写,哪些是typeof判断,哪些是toString判断?思考下 */
getType([]) // "Array" typeof []是object,因此toString返回
getType('123') // "string" typeof 直接返回
getType(window) // "Window" toString返回
getType(null) // "Null"首字母大写,typeof null是object,需toString来判断
getType(undefined) // "undefined" typeof 直接返回
getType() // "undefined" typeof 直接返回
getType(function(){}) // "function" typeof能判断,因此首字母小写
getType(/123/g) //"RegExp" toString返回
以上就是Js中检测数据的三种方法,最后实现了一个通用类检测方法,基本上可以搞定所有数据类型的检测,每一种方法都有自己的强项和不足,我们在使用过程中,还是要看业务场景具体选择!
开源项目传送门:github.crmeb.net/u/xingfu
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!