数据类型检测
typeof
使用typeof操作符一般只适用于原始类型与引用类型的判断,无法进一步区分引用类型之间的不同复杂类型。
typeof null === 'object'
还有这样的历史遗留bug存在,在判断是否为null时直接使用value === null
即可。
instanceof
使用instanceof通常是在判断一个引用类型是否某种复杂引用类型。
A instanceof B
的判断逻辑如下:
- 获取A的原型
proto = Object.getPrototypeOf(A)
- 判断A的原型是否与B的prototype一致
proto === B.prototype
, 一致则返回true,不一致则继续 - 获取proto的原型对象,继续按照前两步来判断。
function myInstanceof (left, right) {
// 首先要判断left是否是引用类型,非引用类型则直接返回false
if (typeof left !== 'object' || left === null) return false;
let proto = Object.getPrototypeOf(left)
while (true) {
// 边界条件判断,如果到达了原型链尽头,则返回false
if (proto === null) {
return false;
}
if (proto === right.prototype) {
return true;
}
proto = Object.getPrototypeOf(proto)
}
}
复制代码
Object.prototype.toString
toString方法可以对JavaScript本身定义的数据类型进行准确的判断,但无法判断用户通过构造函数自定义的复杂类型
- 原始类型的数据,toString返回为
object <对应的包装类型>
,即number类型返回object Number
,string类型返回object String
,以及object Undefined
,object Null
,原因在于toString会首先隐式转换原始类型的数据为对应的包装类型。 - 引用类型的数据,toString返回
object <复杂引用类型>
,如object Function
,object Array
,object RegExp
,Object HTMLDocument
统一的类型检测方法
结合typeof 和 Object.prototype.toString进行统一类型检测
function getType(value) {
if (typeof value !== 'object') {
return typeof value
}
// 将[object <复杂引用类型>]只提取复杂引用类型返回
return Object.prototype.toString.call(value).replace(/^\[object(\S+)\]$/, '$1')
}
复制代码
类型转换
显示类型转换
Number
规则
- 布尔值转换为0或1
- 数字返回自身
- null返回0
- undefined转换为NaN
- 字符串:
- 只包含数字,则转换为十进制数字
- 包含有效浮点格式,转换为浮点数
- 空字符串转换为0
- 以上都不是,转换为NaN
- Symbol类型:
- 抛出错误
- 对象:
- 如果部署了
[Symbol.toPrimitive]
方法,则调用该方法得到返回值 - 否则对象先调用valueOf方法,根据valueOf方法的返回值再根据前述的规则进行转换
- 如果部署了
parseInt
parseFloat
toString
String
Boolean
隐式类型转换
常用的场景是相等比较符与+号操作符
相等操作符
- null或undefined必须与null或undefined才会返回true
- 其中一个是Symbol类型,返回false
- 两个都是string或者number,则将字符串转换为number
- boolean类型会转换为number
- object类型会转为原始类型再判断
+号
- 有字符串存在时,使用拼接功能
- 没有字符串,但有数字时,使用加法功能
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END