1 强制类型转换

Number()、parseInt()、parseFloat()、toString()、String()、Boolean()

1.1 Boolean

要将一个其他类型的值转换为布尔值,可以调用特定的Boolean() 转型函数。
如果 JavaScript 预期某个位置应该是布尔值,会将该位置上现有的值自动转为布尔值。
转换规则是除了下面六个值被转为false,其他值都视为true

  • false
  • undefined
  • 0NaN(Number)
  • ""''(String)
  • null(Object)

  • 空数组([])和空对象({})对应的布尔值,都是true

    1.2 数值转换

    Number()

    1. Number(true); // 1
    2. Number(null); // 0
    3. Number(undefined); // NaN
    4. Number(""); // 0
    5. Number("Hello world!"); // NaN
    6. Number("000011"); // 11

    考虑到用Number() 函数转换字符串时相对复杂且有点反常规,通常在需要得到整数时可以优先使用parseInt() 函数。

parseInt()

如果第一个字符不是数值字符、加号或减号,parseInt()立即返回NaN。

  • 如果parseInt的第一个参数不是字符串,会被先转为字符串。
  • parseInt的返回值只有两种可能,要么是一个十进制整数,要么是NaN
  • 如果字符串以0x0X开头,parseInt会将其按照十六进制数解析
  • 如果字符串以0开头,将其按照10进制解析。
  • parseInt方法还可以接受第二个参数(2到36之间),表示被解析的值的进制,返回该值对应的十进制数。默认情况下,parseInt的第二个参数为10,即默认是十进制转十进制。 ```javascript parseInt(‘123’) // 123 parseInt(‘ 81’) // 81 parseInt(‘1.23’) // 1

//如果parseInt的参数不是字符串,则会先转为字符串再转换。 parseInt(1.23) // 1

parseInt(‘15e2’) // 15 parseInt(‘.3’) // NaN parseInt(‘+1’) // 1

parseInt(‘1000’, 2) // 8 parseInt(‘1000’, 6) // 216 parseInt(‘1000’, 8) // 512

  1. <a name="DoGgS"></a>
  2. #### parseFloat
  3. `parseFloat`方法用于将一个字符串转为浮点数,只能为十进制。<br />如果字符串符合科学计数法,则会进行相应的转换。
  4. ```javascript
  5. parseFloat("0xA"); // 0
  6. parseFloat("22.5"); // 22.5
  7. parseFloat("22.34.5"); // 22.34
  8. parseFloat("0908.5"); // 908.5


2 隐式类型转换

2.1 ‘==’ 的隐式类型转换规则

  • 如果类型相同,无须进行类型转换;
  • 如果其中一个操作值是 null 或者 undefined,那么另一个操作符必须为 null 或者 undefined,才会返回 true,否则都返回 false;
  • 如果其中一个是 Symbol 类型,那么返回 false;
  • 两个操作值如果为 string 和 number 类型,那么就会将字符串转换为 number;
  • 如果一个操作值是 boolean,那么转换成 number;
  • 如果一个操作值为 object 且另一方为 string、number 或者 symbol,就会把 object 转为原始类型再进行判断(调用 object 的 valueOf/toString 方法进行转换)。

    1. null == undefined // true 规则2
    2. null == 0 // false 规则2
    3. '' == null // false 规则2
    4. '' == 0 // true 规则4 字符串转隐式转换成Number之后再对比
    5. '123' == 123 // true 规则4 字符串转隐式转换成Number之后再对比
    6. 0 == false // true e规则 布尔型隐式转换成Number之后再对比
    7. 1 == true // true e规则 布尔型隐式转换成Number之后再对比
    8. var a = {
    9. value: 0,
    10. valueOf: function() {
    11. this.value++;
    12. return this.value;
    13. }
    14. };
    15. // 注意这里a又可以等于1、2、3
    16. console.log(a == 1 && a == 2 && a ==3); //true f规则 Object隐式转换
    17. // 注:但是执行过3遍之后,再重新执行a==3或之前的数字就是false,因为value已经加上去了,这里需要注意一下

    2.2 ‘+’ 的隐式类型转换规则

  • 如果两边都是字符串,则直接拼接,无须进行隐式类型转换

  • 如果其中有一个是字符串,另外一个是 undefined、null 或布尔型,则调用 toString() 方法进行字符串拼接;如果是纯对象、数组、正则等,则默认调用对象的转换方法会存在优先级,然后再进行拼接。
  • 如果其中有一个是数字,另外一个是 undefined、null、布尔型或数字,则会将其转换成数字进行加法运算,对象的情况还是参考上一条规则。
  • 如果其中一个是字符串、一个是数字,则按照字符串规则进行拼接。
    1. 1 + 2 // 3 常规情况
    2. '1' + '2' // '12' 常规情况
    3. // 下面看一下特殊情况
    4. '1' + undefined // "1undefined" 规则1,undefined转换字符串
    5. '1' + null // "1null" 规则1,null转换字符串
    6. '1' + true // "1true" 规则1,true转换字符串
    7. '1' + 1n // '11' 比较特殊字符串和BigInt相加,BigInt转换为字符串
    8. 1 + undefined // NaN 规则2,undefined转换数字相加NaN
    9. 1 + null // 1 规则2,null转换为0
    10. 1 + true // 2 规则2,true转换为1,二者相加为2
    11. 1 + 1n // 错误 不能把BigInt和Number类型直接混合相加
    12. '1' + 3 // '13' 规则3,字符串拼接
    整体来看,如果数据中有字符串,JavaScript 类型转换还是更倾向于转换成字符串

Object 的转换规则

对象转换的规则,会先调用内置的 [ToPrimitive] 函数,其规则逻辑如下:

  • 如果部署了 Symbol.toPrimitive 方法,优先调用再返回;
  • 调用 valueOf(),如果转换为基础类型,则返回;
  • 调用 toString(),如果转换为基础类型,则返回;
  • 如果 vauleOf 和 toString 两个方法都不返回基本类型值,便会触发一个 TypeError 的错误。 ```javascript var obj = { value: 1, valueOf() { return 2; }, toString() { return ‘3’ }, Symbol.toPrimitive { return 4 } } console.log(obj + 1); // 输出5 // 因为有Symbol.toPrimitive,就优先执行这个;如果Symbol.toPrimitive这段代码删掉, // 则执行valueOf打印结果为3;如果valueOf也去掉,则调用toString返回’31’(字符串拼接) // 再看两个特殊的case:

10 + {} // “10[object Object]”,注意:{}会默认调用valueOf是{},不是基础类型继续转换, // 调用toString,返回结果”[object Object]”,于是和10进行’+’运算,按照字符串拼接规则来,参考’+’的规则

[1,2,undefined,4,5] + 10 // “1,2,,4,510”,注意[1,2,undefined,4,5]会默认先调用valueOf结果还是这个数组, // 不是基础数据类型继续转换,也还是调用toString,返回”1,2,,4,5”, // 然后再和10进行运算,还是按照字符串拼接规则,参考’+’的第3条规则 ```

参考自: JavaScript 核心原理精讲-lagou

在执行加法操作的时候,V8 会通过 ToPrimitve 方法将对象类型转换为原生类型,最后就是两个原生类型相加,如果其中一个值的类型是字符串时,则另一个值也需要强制转换为字符串,然后做字符串的连接运算。在其他情况时,所有的值都会转换为数字类型值,然后做数字的相加。
image.png
https://zh.javascript.info/object-toprimitive