[例]
JavaScript 隐式转换与相等三角图
[例] JavaScript 隐式转换与相等三角图
JavaScript 没有把
true + 1
true + 1
留作未定义,而是明确规定转换后得到
2
2
。同样,宽松相等(loose equality)
==
==
规定了按两边种类进行转换的规则;严格相等(strict equality)
===
===
则不做这种转换,不同种类的操作数直接判为不相等。把两种比较放在一起看:
true + 1; // 2:true 转换为 1
[] == 0; // true
[] === 0; // false
0 == "0"; // true
0 === "0"; // false
[] == "0"; // false
[] === "0"; // false
true + 1; // 2:true 转换为 1
[] == 0; // true
[] === 0; // false
0 == "0"; // true
0 === "0"; // false
[] == "0"; // false
[] === "0"; // false
图中每条边同时列出
==
==
和
===
===
的结果,不是归约箭头。绿色实线表示
==
==
为真,红色虚线表示
==
==
为假;第二行单独记录
===
===
,这里三条边都为假。
[] == 0
[] == 0
会先把空数组转换成空字符串
""
""
,再因另一边是数字而把
""
""
转成
0
0
;
0 == "0"
0 == "0"
会把字符串
"0"
"0"
转成数字
0
0
,所以这两条边都为真。但
[] == "0"
[] == "0"
把数组转成
""
""
后,两边已经都是字符串,只比较
""
""
与
"0"
"0"
,结果为假。具体转换规则见 MDN 的
==
==
文档。
传递性(transitivity)要求: 与 相等、 与 相等,就能推出 与 相等。这个三角图正好展示
==
==
不满足传递性,不能像数学等号那样用于替换或推理。
===
===
不会做上述转换:数组、数字、字符串种类不同,所以这三个比较都为假。它回答的是另一个问题,而不是“同一套转换做得更严格”。
但
===
===
也不等于完整的数学等价关系。自反性(reflexivity)要求每个值都与自身相等,而
NaN === NaN
NaN === NaN
为
false
false
。对对象,
===
===
比较的是是否为同一个对象,不是内容是否相同:
const a = []; a === a
const a = []; a === a
为
true
true
,
[] === []
[] === []
却为
false
false
,因为后者创建了两个不同的数组。严格相等的完整规则见 MDN 的
===
===
文档。