前言
类型判断,在我们平时的工作中会经常使用到。比如,判断给定值是否是数字,字符串,布尔值和数组等类型。
typeof
typeof 应该是我们最常用地用于判断数据类型的一种方式了。
Example:
1 | typeof 1 // 'number' |
typeof 介绍:
typeof 操作符返回一个字符串,表示未经计算的操作数的类型。
最新的 ECMAScript 标准定义了8种数据类型:
- 7种基本数据类型
- Number
- String
- Boolean
- null
- undefined
- Symbol
- BigInt
- 引用类型
对这8种数据类型分别使用 typeof:
1 | typeof 1 // 'number' |
可以看到,得到的结果与它们的类型并非完全一一对应。
null 返回了 ‘object’,而非我们期望的 ‘null’;[1] 返回了 ‘object’,而非 ‘array’。
在 javascript 中,可以说一切皆对象。数组是对象,函数是对象,对象是对象,哈哈,但是 typeof 却可以检测出函数的类型:
1 | typeof function(){} // 'function' |
现在我们知道了,typeof 可以检测出: Number, String, Boolean, undefined, Symbol, BigInt, Function 类型。
但是,对于 Array, Object, Arguments 等对象似乎无能为力。
1 | typeof [] // 'object' |
难道我们真的没有办法检测出它们的真实类型吗?
我想我们还是有办法的。
Object.prototype.toString
toString()方法返回一个表示该对象的字符串,格式: ‘[object type]’,type 表示对象的类型
来自MDN:
为了每个对象都能通过 Object.prototype.toString() 的检测,需要以 Function.prototype.call() 或者 Function.prototype.apply() 的形式来调用,传递要检查的对象作为第一个参数,称为 thisArg。
看个例子:
1 | const protoToString = Object.prototype.toString |
Object.prototype.toString 方法可以检测出多少种类型呢? '几乎’所有的类型。这里用几乎是因为我发现,
1 | protoToString.call(new Proxy({},()=>{}))// '[object Object]' |
和预期的 ‘[object Proxy]’ 不一致,以后找到原因了再更新。
type API
既然通过 Object.prototype.toString 可以检测出几乎所有的类型,那么我们可以将其封装成一个函数: 将要检测的值传递到该函数,经过判断返回值的数据类型。
我的设想:
写一个 type 函数,它能检测各种数据类型的值。如果是基本类型,就使用 typeof;引用类型就使用 toString 方法。此外鉴于 typeof 的结果是小写,我也希望所有的结果都是小写。
1 | /** |
封装常用的 API
isNumber
1 | function isNumber(value) |
isString
1 | function isString(value) |
isNull
1 | function isNull(value) |
isUndefined
1 | function isUndefined(value) |
isBoolean
1 | function isBoolean(value) |
isSymbol
1 | function isSymbol(value) |
isObject
1 | function isObject(value) |
isArray
对于数组的检测,我更推荐 ES6 的 Array.isArray API,它用来检测数组类型。目前,所有主流浏览器都已经支持该接口。
当然,如果你想兼容老的浏览器,那就使用 Object.prototype.toString 吧。
1 | function isArray(value) |
isFunction
1 | function isFunction(value) |
isArguments
1 | function isArguments(value) |
isArrayLike
检测 类数组(array-like)对象,可以参考下jQuery或者lodash的源码
1 | function isArrayLike(value) |
isPlainObject
检测 对象字面量(纯对象)
1 | function isPlainObject(value) |
好吧,我直接抄的 lodash
做一下验证:
1 | isPlainObject([]) // false |
- Post title:JavaScript专题之类型判断
- Post author:w2xi
- Create time:2022-02-02 15:24:40
- Post link:https://w2xi.github.io/2022/02/02/JavaScript专题之类型判断/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.