类型转换规则

Posted Miya

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了类型转换规则相关的知识,希望对你有一定的参考价值。

下面的代码会输出什么?为什么?

console.log(1 +  "2" + "2");
console.log(1 +  +"2" + "2");
console.log(1 +  -"1" + "2");
console.log(+"1" +  "1" + "2");
console.log( "A" - "B" + "2");
console.log( "A" - "B" + 2);

结果是:

console.log(1 +  "2" + "2");  //122
console.log(1 +  +"2" + "2");  //32
console.log(1 +  -"1" + "2");  //02
console.log(+"1" +  "1" + "2");  //112
console.log( "A" - "B" + "2");  //NaN2
console.log( "A" - "B" + 2);  //NaN

数值转换

有 3 个函数可以把非数值转换为数值:Number()、parseInt()和 parseFloat()。

Number()函数的转换规则如下。

  1. 如果是 Boolean 值,true 和 false 将分别被转换为 1 和 0。
  2. 如果是数字值,只是简单的传入和返回。
  3. 如果是 null 值,返回 0。
  4. 如果是 undefined,返回 NaN。
  5. 如果是字符串,遵循下列规则:

    • 如果字符串中只包含数字(包括前面带正号或负号的情况),则将其转换为十进制数值,即"1" 会变成 1,"123"会变成 123,而"011"会变成 11(注意:前导的零被忽略了);
    • 如果字符串中包含有效的浮点格式,如"1.1",则将其转换为对应的浮点数值(同样,也会忽 略前导零);
    • 如果字符串中包含有效的十六进制格式,例如"0xf",则将其转换为相同大小的十进制整 数值;
    • 如果字符串是空的(不包含任何字符),则将其转换为 0;
    • 如果字符串中包含除上述格式之外的字符,则将其转换为 NaN。
  6. 如果是对象,则调用对象的 valueOf()方法,然后依照前面的规则转换返回的值。如果转换的结果是 NaN,则调用对象的 toString()方法,然后再次依照前面的规则转换返回的字符串值。

在对非数值应用一元加操作符时,该操作符会像 Number()转型函数一样对这个值执行转换。 换句话说,布尔值 false 和 true 将被转换为 0 和 1,字符串值会被按照一组特殊的规则进行解析,而对象是先调用它们的valueOf()和(或)toString()方法,再转换得到的值。

递增和递减操作符---类型转换规则

递增和递减操作符操作符对任何值都适用,也就是它们不仅适用于整数,还可以用于字符串、布尔值、浮点数值和对象。在应用于不同的值时,递增和递减操作符遵循下列规则。

  1. 在应用于一个包含有效数字字符的字符串时,先将其转换为数字值,再执行加减 1 的操作。字符串变量变成数值变量。
  2. 在应用于一个不包含有效数字字符的字符串时,将变量的值设置为NaN(第4章将详细讨论)。字符串变量变成数值变量。
  3. 在应用于布尔值 false 时,先将其转换为 0 再执行加减 1 的操作。布尔值变量变成数值变量。
  4. 在应用于布尔值 true 时,先将其转换为 1 再执行加减 1 的操作。布尔值变量变成数值变量。
  5. 在应用于浮点数值时,执行加减 1 的操作。
  6. 在应用于对象时,先调用对象的valueOf()方法(第5章将详细讨论)以取得一个可供操作的值。然后对该值应用前述规则。如果结果是 NaN,则在调用 toString()方法后再应用前述规则。对象变量变成数值变量。

乘法操作符---类型转换规则

  1. 如果操作数都是数值,执行常规的乘法计算,即两个正数或两个负数相乘的结果还是正数,而如果只有一个操作数有符号,那么结果就是负数。如果乘积超过了 ECMAScript 数值的表示范围,则返回 Infinity 或-Infinity;
  2. 如果有一个操作数是 NaN,则结果是 NaN;
  3. 如果是 Infinity 与 0 相乘,则结果是 NaN;
  4. 如果是 Infinity 与非 0 数值相乘,则结果是 Infinity 或-Infinity,取决于有符号操作数的符号;
  5. 如果是 Infinity 与 Infinity 相乘,则结果是 Infinity;
  6. 如果有一个操作数不是数值,则在后台调用 Number()将其转换为数值,然后再应用上面的规则。

除法操作符---类型转换规则

  1. 如果操作数都是数值,执行常规的除法计算,即两个正数或两个负数相除的结果还是正数,而如果只有一个操作数有符号,那么结果就是负数。如果商超过了 ECMAScript 数值的表示范围,则返回 Infinity 或-Infinity;
  2. 如果有一个操作数是 NaN,则结果是 NaN;
  3. 如果是 Infinity 被 Infinity 除,则结果是 NaN;
  4. 如果是零被零除,则结果是 NaN;
  5. 如果是非零的有限数被零除,则结果是 Infinity 或-Infinity,取决于有符号操作数的符号;
  6. 如果是 Infinity 被任何非零数值除,则结果是 Infinity 或-Infinity,取决于有符号操作数的符号;
  7. 如果有一个操作数不是数值,则在后台调用 Number()将其转换为数值,然后再应用上面的规则。

求模操作符---类型转换规则

  1. 如果操作数都是数值,执行常规的除法计算,返回除得的余数;
  2. 如果被除数是无穷大值而除数是有限大的数值,则结果是 NaN;
  3. 如果被除数是有限大的数值而除数是零,则结果是 NaN;
  4. 如果是 Infinity 被 Infinity 除,则结果是 NaN;
  5. 如果被除数是有限大的数值而除数是无穷大的数值,则结果是被除数;
  6. 如果被除数是零,则结果是零;
  7. 如果有一个操作数不是数值,则在后台调用 Number()将其转换为数值,然后再应用上面的规则。

加法操作符---类型转换规则

  1. 如果有一个操作数是 NaN,则结果是 NaN;
  2. 如果是 Infinity 加 Infinity,则结果是 Infinity;
  3. 如果是-Infinity 加-Infinity,则结果是-Infinity;
  4. 如果是 Infinity 加-Infinity,则结果是 NaN;
  5. 如果是+0 加+0,则结果是+0;
  6. 如果是-0 加-0,则结果是-0;
  7. 如果是+0 加-0,则结果是+0。

不过,如果有一个操作数是字符串,那么就要应用如下规则:

  1. 如果两个操作数都是字符串,则将第二个操作数与第一个操作数拼接起来;
  2. 如果只有一个操作数是字符串,则将另一个操作数转换为字符串,然后再将两个字符串拼接起来。
  3. 如果有一个操作数是对象、数值或布尔值,则调用它们的toString()方法取得相应的字符串值,然后再应用前面关于字符串的规则。对于 undefined 和 null,则分别调用 String()函数并取得字符串"undefined"和"null"。

减法操作符---类型转换规则

  1. 如果两个操作符都是数值,则执行常规的算术减法操作并返回结果;
  2. 如果有一个操作数是 NaN,则结果是 NaN;
  3. 如果是 Infinity 减 Infinity,则结果是 NaN;
  4. 如果是-Infinity 减-Infinity,则结果是 NaN;
  5. 如果是 Infinity 减-Infinity,则结果是 Infinity;
  6. 如果是-Infinity 减 Infinity,则结果是-Infinity;
  7. 如果是+0 减+0,则结果是+0;
  8. 如果是+0 减-0,则结果是-0;
  9. 如果是-0 减-0,则结果是+0;
  10. 如果有一个操作数是字符串、布尔值、null或undefined,则先在后台调用Number()函数将其转换为数值,然后再根据前面的规则执行减法计算。如果转换的结果是 NaN,则减法的结果就是 NaN;
  11. 如果有一个操作数是对象,则调用对象的valueOf()方法以取得表示该对象的数值。如果得到的值是NaN,则减法的结果就是 NaN。如果对象没有 valueOf()方法,则调用其 toString()方法并将得到的字符串转换为数值。

关系操作符---类型转换规则

小于(<) 、大于(>) 、小于等于(<=)和大于等于(>=)

  1. 如果两个操作数都是数值,则执行数值比较。
  2. 如果两个操作数都是字符串,则比较两个字符串对应的字符编码值。
  3. 如果一个操作数是数值,则将另一个操作数转换为一个数值,然后执行数值比较。
  4. 如果一个操作数是对象,则调用这个对象的 valueOf()方法,用得到的结果按照前面的规则执行比较。如果对象没有 valueOf()方法,则调用 toString()方法,并用得到的结果根据前面的规则执行比较。
  5. 如果一个操作数是布尔值,则先将其转换为数值,然后再执行比较。在使用关系操作符比较两个字符串时,会执行一种奇怪的操作。很多人都会认为,在比较字符串值时,小于的意思是“在字母表中的位置靠前”,而大于则意味着“在字母表中的位置靠后”,但实际上完全不是那么回事。在比较字符串时,实际比较的是两个字符串中对应位置的每个字符的字符编码值。经过这么一番比较之后,再返回一个布尔值。由于大写字母的字符编码全部小于小写字母的字符编码,因此我们就会看到奇怪现象。

相等和不相等操作符---类型转换规则

在转换不同的数据类型时,相等和不相等操作符遵循下列基本规则:

  1. 如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值——false 转换为 0,而true 转换为 1;
  2. 如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前先将字符串转换为数值;
  3. 如果一个操作数是对象,另一个操作数不是,则调用对象的valueOf()方法,用得到的基本类型值按照前面的规则进行比较;

这两个操作符在进行比较时则要遵循下列规则。

  1. null 和 undefined 是相等的。
  2. 要比较相等性之前,不能将 null 和 undefined 转换成其他任何值。
  3. 如果有一个操作数是 NaN,则相等操作符返回false,而不相等操作符返回true。重要提示:即使两个操作数都是NaN,相等操作符也返回 false;因为按照规则, NaN 不等于 NaN。
  4. 如果两个操作数都是对象,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,则相等操作符返回true;否则,返回 false。

相等和不相等——先转换再比较, 全等和不全等——仅比较而不转换。

参考《javascript高级程序设计》

算术运算符 - MDN

以上是关于类型转换规则的主要内容,如果未能解决你的问题,请参考以下文章

类型转换规则

强制类型转换

何谓隐式类型转换?其转换规则如何?

基本数据类型转换6条规则

java 强制类型转换的规则是啥?

C语言数据类型转换基本规则