强制类型转换
值类型转换
包括两种:显式转换和隐式转换。
将值从一种类型转换为另外一种类型称为类型转换,也叫做显式类型转换,隐式的情况也叫做强制类型转换。在js中两种转换被统称为强制类型转换。
其实,对于显式和隐式没有很明确的界定,如果你不知道某种情况是一种显式类型转换,那么它对于你来讲就是隐式的。
抽象值操作
- ToString
1)基本类型值:null转化为 “null”, undefined转化为 “undefined”, true转化为 “true”, 极大极小的数字会先转化为指数形式再转化为字符串。
2)普通对象:除非自己定义,否则将返回内部属性[[Class]]的值(Object.prototype.toString())。一般来讲,内部属性[[Class]]与创建该对象时的内建原生构造函数相对应,如数组的内部[[Class]]属性为 “Array”以及正则表达式的值是 “RegExp”,但是也有例外,如null和undefined没有对应的构造函数,但仍然返回Null和Undefined。
3)数组:将所有单元字符串化后再用 “,”连接。
4)JSON.stringify(..):将对象序列化为字符串时也用到了ToString。JSON.stringify(..)在对象中遇到undefined、function和symbol时会自动将其忽略,在数组中遇到它们时则会返回null。如果对象中定义了toJSON()的方法,那么在执行JSON.stringify(..)时会先调用toJSON()方法然后用它返回的值来进行序列化。
不安全的JSON值:undefined、function、symbol以及包含循环引用的对象,我们可以通过定义toJSON()返回一个安全的JSON值。 - ToNumber
1)true转换为1,false转换为0,undefined转换为NaN,null转换为0。
2)处理失败时返回NaN。
3)对于0开头的十六进制数按照十进制处理。
4) “”、 “\n”、 “ ” 等空字符串被转换为0。
5)对象(包括数组):先转换为相应的基本类型值,若返回的是非数字的基本类型值,再进一步转化成数字。
将对象转换为基本类型值:抽象操作ToPrimitive首先检查该值是否有valueOf()方法,若有并且返回基本类型值,那就用这个值进行强制类型转换,如果没有就使用toString()的返回值进行强制类型转换,如果都没有返回值,会产生TypeError错误。 - ToBoolean
1)假值:undefined、null、false、+0、-0、NaN、 “”,这些值的布尔强制类型转换结果为false。
2)js规范没有明确说假值列表以外的值都应该是真值,但是可以这么理解。
显示强制类型转换
字符串和数字
1)内建函数:String() & Number()。
2).toString()转换为字符串类型:因为toString()对基本类型值不适用,所以js引擎会先喂基本类型值创建一个封装对象,然后再对此对象调用toString()。
3)“+”或者“-”转换为数字类型:但是“-”会反转数字的符号位,要用“- -”,注意不要连写减号,否则会被当作递减运算符来处理。
4)日期转换为数字
返回当前时间戳(从1970年1月1日00:00:00 UTC到当前的时间,单位是ms)
方法一:var timestamp = +new Date();
方法二:var timestamp = new Date().getTime();
方法三:var timestamp = Date.now();
推荐使用方法二和三5)字位运算符“~”(非)或者“|”(或)
字位运算符只适合32位整数,运算符会强制操作数使用32位格式,这是通过ToInt32实现的,ToInt32首先执行ToNumber强制类型转换,然后再执行ToInt32。
在这里有一个应用那就是利用“~”和indexOf()来实现搜索。显示解析数字字符串
1)paseInt():允许字符串中含有非数字字符,从左往右解析,遇到非数字就停止解析。
2)parseFloat():解析字符串中的浮点数。
3)如果第一个字符是x或者X,则转换为十六进制数字,如果第一个字符是0,转换为八进制数字,其他情况如果没有指定就是十进制。
4)在解析之前,非字符串参数会首先被强制转换为字符串,但是要尽量避免产生这种隐式转换,即不要向parseInt()传递非字符串参数。显示转换为布尔值
1)Boolean():不常用。
2)“!!”:常用。
3)在if(..)..这样的布尔值上下文中,如果没有使用Boolean(..)或者!!,就会自动隐式进行ToBoolean转换,建议先使用Boolean(..)或者!!进行显式转换,提高代码的可读性。
隐式强制类型转换
作用就是减少冗余,让代码更简洁。
字符串和数字之间
1)数字转字符串:数字和空字符串”“相+来将数字转换为字符串。
2)字符串转数字:通过字符串与0相-或者与1相*(/)都可以将字符串转换为数字。转换为布尔值
1)if( .. )语句中的条件判断表达式。
2)for( .. ; .. ; .. )语句中的条件判断表达式(第二个)。
3)while( .. )和do..while( .. )循环中的条件判断表达式。
4)? :中的条件判断表达式。
5)逻辑运算符||(逻辑或)和&&(逻辑与)左边的操作数(作为条件判断表达式)。符号强制类型转换
es6中引入了符号类型,只允许从符号到字符串的显示强制类型转换以及到布尔值的转换(结果都为true)。安全使用隐式强制类型转换
两原则:
1)如果两边的值有true或false,千万不要使用==;
2)如果两边的值有[]、”“或者0,尽量不要使用==。
宽松相等和严格相等
宽松相等:==,允许在相等比较时进行强制类型转换;
严格相等:===,不允许。
- 抽象相等 ==
1)字符串和数字
如果Type(x)是数字,Type(y)是字符串,则返回x==ToNumber(y)的结果;如果Type(x)是字符串,Type(y)是数字,则返回ToNumber(x)==y的结果。总结就是,转成数字类型再比较。
2)其他类型和布尔类型
如果Type(x)是布尔类型,则返回ToNumber(x)==y的结果;如果Type(y)是布尔类型,则返回x==ToNumber(y)的结果。总结就是,布尔类型先要转成数字类型再比较。
建议:无论何时都不要使用==true和==false。
3)null和undefined
如果x为null,y为undefined,结果为true;如果x为undefined,y为null,结果也为true。总结来说,在==中null和undefined是一回事。
4)对象和非对象
如果Type(x)是字符串或数字,Type(y)是对象,则返回x==ToPrimitive(y)的结果;如果Type(x)是对象,Type(y)是数字或字符串,则返回ToPrimitive(x)==y的结果。总结就是,先对对象进行ToPrimitive抽象操作再比较。(在ToNumber的5中有ToPrimitive抽象操作的过程介绍)
以上知识是本人在学习《你不知道的js(中卷)》强制类型转换一部分的时候的一些总结。