js中隐式转换,就是在进行一些运算时,js在解析过程中,自动的调取一些函数或方法,按照一定的规则,进行数据类型的转换,从而完成运算的过程。
为了充分的理解隐式转换,下面从数据类型、类型转换的方法、运算符三个维度来进行总结。
首先来捋一捋基础:
js中的数据类型分为:Number、String、Boolean、Null、Undefined、Object六大类型。其中Number、String、Boolean为简单数据类型,Object为复杂数据类型,Null、Undefined为空类型。
常见的类型转换方法:
1.转数字类型:Number()、parseInt()、parseFloat()
2.转字符串:String()、对象.toString()
3.转布尔值:Boolean()
运算符及其优先级:(见下图)
(一些常见的显示转换):
Number(NaN); //NaN
String(NaN); //"NaN"
Boolean(NaN); //false
Number(null); //0 数字0
String(null); //"null"
Boolean(null); //false
Number(undefined); //NaN
String(undefined); //"undefined”
Boolean(undefined); //false
Number(''); //0 数字0
String(''); //""
Boolean(''); //false
Number('0'); //0 数字0
String('0'); //"0”
Boolean('0'); //true
Number(false); //0 数字0
String(false); //"false”
Boolean(false); //false
Number([]); //0 数字0
String([]); //""
Boolean([]); //true
Number({})); //NaN
String({})); //"[object Object]"
Boolean({})); //true
接下来进入正题:
在运算中,隐式转换首先要遵循的就是运算符的优先级.
在以下操作符解析时,会进行以下隐式转换:
① ! 逻辑取反。 所有类型(包括对象)直接执行Boolean()转成布尔类型 。然后再做取反!操作。
② + 二元加法运算符。 如果算式内有 字符串 那么+两端的任何数据类型都转成字符串,进行字符串拼接;
但是如果算式内没有字符串,也没有复杂类型,那么就会对其他类型的数据执行Number()操作,转成number类型,再进行加法运算,
如果数据类型是对象,那么先调用它的valueOf()或toString()方法(具体用那种转换方式?一般情况会默认调用valueOf(),没有valueOf()或得到的不是原始值则调用toString()),然后再执行Number()。
③ 其它情况下:
对非数字的数据类型执行Number()转型操作,转成数字。
如果数据类型是对象,那么先调用它的valueOf()或toString()方法(具体用那种转换方式?一般情况会默认调用valueOf(),没有valueOf()或得到的不是原始值则调用toString()),然后再执行Number()。
④ 几个特殊理解的情况:
❶ NaN和任和都不相等,包括它自己。进行任何比较运算都是false。进行任何算数运算结果都是NaN。
❷ 进行位运算时,NaN、Infinity(无穷),这两个在进行位操作时会被当做0来处理。(这是由于在位运算时,要从存储时的64位变成位运算的32位,而产生的负效应)
❸null 除了自己和undefined外,其它任何类型都不相等。
undefined 除了自己和null外,其它任何类型都不相等。
其它情况下遵循③。
❹ 字符串之间的比较运算,比较的是字符编码。从左往右,对位比较。长度不一,后面补0.
❺复杂类型之间的比较是内存地址的比较。
❻所有的复杂类型转换成布尔类型都是true。
❼{} + [];//0 原因:当{}既可以被理解为"复合语句块"也可以被理解为"对象直接量"或"函数声明"的时候,JavaScript将会将其理解成为复合语句块。根据语句优先原则,{}被理解为复合语句块,因此相当于 {}; +[]。[]为空,Number([])为0,所以结果为0。
❽(这条不算特殊,写这里看看+±-过程)前置++ 前置-- 后置++ 后置-- 。对非数字的数据类型,先执行Number(),转换成数字值,再执行前置++ – 后置++ --(不同的是前置是完成转换后先+±-再参与其他运算或输出。而后置是转换完成后先参与其它运算或输出,然后再+±-)。
如果数据类型是对象,那么先调用它的valueOf()或toString()方法(具体用那种转换方式?一般情况会默认调用valueOf(),没有valueOf()或得到的不是原始值则调用toString()),然后再执行Number(),最后再执行前置++ – 后置++ --。
❾暂时就想到这么多,如果有什么遗漏或者有什么错误的地方,欢迎大家批评指正。