类型判断在业务开发,边界问题上可以体现你技术水平的高低
变量类型
ES2023一共定义了 Undefined、Null、Boolean、String、Symbol、Number、Object 七种类型,除了Object作为复杂类型,其他均为原始类型
Number下同时还存在一个特殊的BigInt类型,Object中也存在如 Function、Array、Date、RegExp这些特殊的对象类型
typeof的特殊
此时会有一个问题,typeof作为Js中的操作符,它的输出结果与我们前面给到的类型并不是一一对应的,比如typeof Function
的结果就是function;typeof null
结果为object;typeof BigInt
结果为bigint
当然平时开发对于null的判断基本全量使用全等判断即可obj === null
,不需要typeof
undefined的特殊
undefined
在JS中并不是关键字,所以当在局部作用域时完全可以被作为变量名使用,比如:
{
const undefined = 1
console.log(typeof undefined) //number
}
所以对于undefined
的判断,请使用"undefined" === tyepof variable
对象的特殊
由于原型链可被重写的缘故,所以对于典型对象如Date、RegExp之类的判断,常用的判断方法有 instanceof、constructor、以及Object.prototype.toString.call
,尽管如此,都没法尽善尽美的做到类型判断。
只有Array下提供了Array.isArray
这个方法可以提供对于数组的准确判断(修改原型链都无法影响到它)
原始类型的装箱和拆箱
除了null和undefined,原始类型都是进行对象的装箱,且它们的类型返回都为Object
Object(123) // new Number(123)
Object(123n) // new BigInt(123n)
Object('str') // new String("str")
Object(true) // new Boolean(false) 特殊!对于返回始终为true
Object(Symbol("sym")) // 特殊!注意Symbol不支持构造函数调用
所以在Lodash.isString
的实现中,为了兼容装箱类型,它的核心实现是这样的:
function isString(str){
return "string" === typeof str || Object.prototype.toString.call(str) === "[object] string"
}
总结
- 使用typeof来判断原始类型、使用全等来判断null
- 使用Array.isArray判断数组
- 没有完美的对象判断方法,任一方法选择使用