# 类型转换

文中的值类型等价于所说的基础类型,其范围是(boolean,string,number)

# 转换为基础类型

# 布尔值

  • undefinednullfalseNaN''0 --> false
  • 其它值都,包括所有对象 --> true

# 数字

  • 数组
    • [] --> 0: 空数组转为0
    • [1] --> 1: 含有一个元素且为数字则转换为数字
    • [1,2] --> NaN: 其余情况转为NaN
    • ['abc',1] --> NaN: 其余情况转为NaN
  • 值类型
    • null --> 0
    • '123' --> 123: 纯数字构成的字符串直接转换为对应的数字
    • true --> 1
    • false --> 0
    • '124a' --> NaN
    • undefined --> NaN
    • Symbol --> 抛出错误
  • 除了数组之外的引用类型(Object) --> NaN

# 字符串

  • 666 --> '666': 数字可直接转为字符串
  • 布尔值:布尔值直接转换
    • true --> 'true'
    • false --> 'false'
  • 数组
    • [] --> '' :空数组转为空串
    • [2,'3'] --> '2,3' :非空数组的每一项转为字符串再用,分割
  • 对象:
    • {} --> [object Object]
    • {a:1} --> [object Object]

# 对象转基础类型规则

对象在转换类型的时候,会调用内置的 [[ToPrimitive]] 函数,对于该函数来说,算法逻辑一般来说如下:

  1. 如果已经是基础类型了,那就不需要转换了
  2. 目标类型为字符串就先调用 toString
    • 转换为基础类型的话就返回转换的值
  3. 目标类型不为字符串就先调用 valueOf
    • 结果为基础类型,就返回转换的值
    • 结果不是基础类型的话再调用 toString
  4. 如果都没有返回基础类型,就会报错

各种情况举例

const demo1 = {
    [Symbol.toPrimitive]: function () {
        return 2
    }
}
// 情况1
console.log(demo1 + 1); // 3

const demo2 = {
    toString() {
        return 'demo2'
    },
    valueOf() {
        return 20
    }
}
// 情况2
console.log(String(demo2)) // demo2

// 情况3-1
console.log(demo2 - 3); // 17

const demo3 = {
    toString() {
        return 30
    },
    valueOf() {
        return {}
    }
}
// 情况3-2
console.log(demo3 - 4); // 26

const demo4 = {
    toString() {
        return {}
    },
    valueOf() {
        return {}
    }
}
// 情况4
console.log(demo4 + 1); // 报错
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

# 四则运算符

# 加法

  • 有一方为String,那么另一方也会被转为String
  • 一方为Number,另一方为原始值类型,则将原始值类型转换为Number
  • 一方为Number,另一方为引用类型,双方都转为String

# 其它

除了加法的运算符来说(-,*,/),会将非Number类型转换为Number类型

转换示例

'123'+4 // '1234'

123+true // 124
123+undefined // NaN
123+null // 123

123+[] //  '123'
123+{} // '123[object Object]'
1
2
3
4
5
6
7
8

# 比较运算符

==

  1. NaN不等于任何其它类型
  2. Boolean 与其它类型进行比较,Boolean转换为Number
  3. StringNumber进行比较,String 转化为Number
  4. nullundefinde进行比较结果为true
  5. null,undefined与其它任何类型进行比较结果都为false
  6. 引用类型值类型进行比较,引用类型先转换为值类型(调用[ToPrimitive])
  7. 引用类型引用类型,直接判断是否指向同一对象

图片

举例

[]==![] // true
// [] == false  1. 根据运算符优先级 ![] --> false
// [] == 0      2. 上面规则2
// '' == 0      3. 上面规则6
//  0 == 0      4. 上面规则3
// 所以结果为true
1
2
3
4
5
6

# 自测

if ([]) console.log(1);             // 1 -- 对象始终为true
if ({}) console.log(2);             // 2 -- 对象始终为true
if ([] == false) console.log(3);    // 3 -- [] == 0 --> '' == 0 --> 0 == 0
if ({} == false) console.log(4);    //   -- {} == 0 --> '[object Object]' == 0  --> NaN == 0 --> NaN不等于任何值
if ([] == ![]) console.log(5);      // 5 -- [] == false --> 同3
if ({} == !{}) console.log(6);      //   -- {} == false --> 同4
if ('' == false) console.log(7);    // 7 -- '' == 0 --> 0 == 0
if (false == 0) console.log(8);     // 8 -- 0 == 0
if (1 == true) console.log(9);      // 9 -- 1 == 1
if ('' == 0) console.log(10);       // 10 -- 0 == 0
if (NaN == NaN) console.log(11);    //    -- NaN不等于任何值
if ([] == !true) console.log(12);   // 12 -- [] == false --> [] == 0 --> '' == 0 ->> 0 == 0
if ([] == false) console.log(13);   // 13 -- 同12 的步骤
if ([] == 0) console.log(14);       // 14 -- '' == 0 --> 0 == 0
if (+0 == -0) console.log(15);      // 15
if (NaN == false) console.log(16);  //    -- NaN不等于任何值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{ } +1              // 1 {} 被解析为是代码块
1 + {}              // '1[object Object]' -- 1 + ’[object Object]‘ --> '1' + [object Object]
[] + 1              // '1' -- '' + 1 --> '' + '1'
1 + []              // '1' -- 1 + '' --> '1' + ''
[1, 2, 3] + 0       // '1,2,30' -- '1,2,3' + 0 --> '1,2,3' + '0'
[1, 2, 3] + '0'     // 同上
1 + '0'             // '10' --  '1' + '0'
1 + 0               // 1
1 + true            // 2 -- 1 + 1
1 + false           // 1 -- 1 + 0
'1' + true          // '1true' -- '1' + 'true'
'1' + false         // '1false' -- '1' + 'false'
![] + []            // 'false' -- false + [] --> false + '' --> 'false' + ''
1 - true            // 0 -- 1 - 1
'0' - 0             // 0 -- 0 - 0
0 - '1'             // -1 -- 0 - 1
false - true        // -1 -- 0 - 1
{ } -[]             // -0 -- -0
[] - {}             // NaN -- '' - [object Object] --> 0 - NaN
false - []          // 0 -- 0 - '' --> 0 - 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20