!、== 、+ 的隐式数据转换

178 阅读3分钟

提出问题,[] + {}{} + []的结果是什么呢 ?
我的第一反应是这这这 是啥,应该是一样吧 ?
当然我自己运行下,就得出了答案,结果不一样呢???为啥呢?? 接下来我们看看隐式转换的知识

!a 操作符号

!a在进行运算时,调用了Boolean方法,将变量转换为boolean值

![];
// 等价于
!Boolean([]); // false

![123]; // false
!{}; // false
!{name: 'bajiu'}; // false
!1; // false
!new String(''); // true
!''; // true
!0; // true
!1; // false
!2; // false

== 操作符号

  1. 如果类型相同,直接比较是否相等,有特殊情况,比如示例
NaN == NaN; // false
  1. 如果其中一个值为undefined,另一个值为null,直接返回true
  2. 其中一个为Symbol类型,直接返回false,存在特殊情况,如示例
// a === b
`Symbol.for(a) == Symbo.for(b)`
  1. 如果值为引用类型,则将引用转换为基本数据类型
  2. 如果其中一个为数字,另外一个基本类型,通过Number方法,将一个值转换为数字,(示例可证明是将其他类型转换为数字)
'123.0' == 123; // true
true == 2; // false
10n == 10; // true
  1. 如果其中为boolean类型,另外一个为基本类型且不为数字,则通过Boolean方法,将另外一个转换为boolean值
true == '123'; // true
true == ''; // false

a + b 拼接 和 计算

步骤如下

  1. 如果不是基本类型,将引用类型转成基本数据类型
  2. 其中一个为string,调用String方法将另外一个转换为字符串,然后比较。
  3. 最后,两个都不为string,调用Number方法,将ab转换为数字

a 和 b都为基本数据类型

  1. 如果其中一方为字符串,则使用String方法,将另一方转换为字符串,进行拼接操作
  2. 如果两个都不会字符串,则使用Number方法,将ab转换为数字,进行计算操作
'hello' + 'bajiu'; // hello bajiu
1 + 'bajiu'; // '1bajiu'
'bajiu' + true; // 'bajiutrue'
1 + true; // 2 

‘bajiu’ + Symbol('test') // 报错 Uncaught TypeError: Cannot convert a Symbol value to a string
1 + Symbol('test'); // 报错 TypeError: Cannot convert a Symbol value to a number

a 、 b为引用类型

当为应用类型的时候,把引用类型转换为基本数据类型,然后进行两个基本数据类型的处理
引用数据类型转换为基本数据类型的步骤

  1. 调用自身的valueOf方法,如果返回结果为基本类型,不执行后续操作
  2. 调用toString方法
1 + []; // '1'

[1] + [2]; // '12' 

[1] + {value: 'bajiu'}; // '1[object Object]'

1 + console.log; // '1function log() { [native code] }'

1 + new Number(12); // 13

1 + new String('bajiu'); // '1bajiu'

1 + new Boolean(true); // 2

'1' + new Number(12); // '112'

1 + new String('bajiu'); // '1bajiu'

1 + new Boolean(true); // 2

{}不是对象

当{}作为代码块时,整体元算等效于 +b,此时会调用Number方法,将b转换为数字,最后结果为数字

// 比较特殊情况
{} + 'baijiu' // NaN
// 等效于
{ let a = 123 } + 'bajiu'
// 等效于
+'bajiu'

思考

看完文章了,我们来测试下是否真的掌握了吧

[] == ![]

这个答案是 true,转换步骤如下

  1. []转换基本类型,依次调用valueoftoString方法,得到基本数据 空字符串
  2. ![]执行时,调用Boolean返回结果 true!true为 false
  3. 此时转换成了 '' == false,将空字符串转换为boolean值false
  4. false == false,结果为true

{} + [] 与 [] + {}

{} + []
这里的{}不是对象,所以等效于+[], 将空数组转换为数字,所以结果为0。

[] + {} 将两个引用类型转换为基本数据类型,'' + '[object Object]',所以结果是[object Object]