[] == ![] !? 浅析JS的类型系统和隐式类型转换 - 掘金 (juejin.cn)
javascript之类型的细节
javascript的变量转换
String的类型转换
显示转换
- 使用toString方法
- 调用String函数
1 | let str = String(123) |
隐式转换
- 一个字符串和别的数值类型进行+操作
- 某些函数的执行也会自动将参数转换成字符串类型例如console.log()
1 | let str = "123" |
Number的类型转换
显示转换
- 使用Number函数转换
隐式转换
- 除了+运算,在别的算数运算中,都会将其他类型转换成数字类型来处理
转换规则
1 | console.log(Number('123hello123'))//NaN |
boolean的类型转换
转换规则
1 | //非空的字符串总是true |
ToPrimitive
当对象需要转换成基本数据类型时,就会执行ToPrimitive过程
ToPrimitive过程先回检查对象是否存在valueOf方法,如果存在并且valueOf返回基本类型的值,则使用该值进行强制类型转换,如果没有,则使用toString方法返回的值进行强制类型转换。
在+运算中,如果其中一个操作数是字符串;或者其中一个操作数是对象,且可以通过ToPrimitive操作转换为字符串,则执行字符串连接操作;其他情况执行加法操作。
1 | console.log(1+true)//2 |
如果在浏览器控制台这样输入则会有不同的表现,那是因为{}被解析成了代码块,因此只是将[]转换成了number
==和===
==和===的区别
===比==更加严格,==在比较两个数据类型不同的值的时候,会进行自动数据类型转换,而===在比较两个数据类型不同的值的时候,会直接返回false
1 | console.log(1=='1')//true |
==的一些特殊表现
- NaN不等于NaN
1 | console.log(NaN == NaN)//false |
- null == 0为false
1 | console.log(Number(null) == 0) //true |
- undefined == null 为true
1 | console.log(null == undefined) |
- 以及上面探讨过的
1 | true + true === 2 // true |
== 的类型转换规则
对于数字和字符串的抽象比较,将字符串进行ToNumber操作后再进行比较
对于布尔值和其他类型的比较,将其布尔类型进行ToNumber操作后再进行比较
对于对象和基础类型的比较,将对象进行ToPrimitive操作后在进行比较
对象之间的比较,引用同一个对象则为true,否则为false
valueOf
valueOf()
函数返回指定对象的原始值。
JavaScript的许多内置对象都重写了该函数,以实现更适合自身的功能需要。因此,不同类型对象的valueOf()
方法的返回值和返回值类型均可能不同。
对象 | 返回值 |
---|---|
Array | 数组实例对象。 |
Boolean | 布尔值。 |
Date | 以毫秒数存储的时间值,从 UTC 1970 年 1 月 1 日午夜开始计算。 |
Function | 函数本身。 |
Number | 数字值。 |
Object | 对象本身。这是默认设置。 |
String | 字符串值。 |
1 | let str = new String(123) |
类型检测
typeof
typeof用于检测类型,但是对于引用类型来说又有一定的局限性,无法区分object类型的子类型
先看两几个例子
1 | console.log(typeof [] === typeof {})//true |
typeof的返回值有number,string,boolean,object,undefined,function,symbol
-
对于number,string,boolean,symbol返回对应的结果
-
对于对象,数组,null返回object
-
对于函数返回function
-
对于定义没有赋值的变量返回undefined
Object.prototype.toString
可以通过Object.prototype.toString来检测每个对象的类型,而不是单纯的返回object
1 | Obejct.prototype.toString.call(undefined); |
使用该种方式无法鉴别基本数据类型还是包装类型,返回值都为[Object xxx]
1 | var num = 42 |
如果这篇文章对你有帮助,可以bilibili关注一波 ~ !此外,如果你觉得本人的文章侵犯了你的著作权,请联系我删除~谢谢!