相等运算符的精简规则
1、 如果 x
或 y
中有一个或者两个都为 NaN
,则返回 false
;1
2
3
4
5NaN == NaN
=> false
NaN == 1
=> false
2、 如果 x
与 y
皆为 null
或 undefined
中的一种类型,则返回 true;否则返回 false;1
2
3
4
5
6
7
8null == undefined
=> true
null == null
=> true
null == 0
=> false
3、 如果 x
与 y
皆为 String、Number、Boolean
中的某一类型,则将 x
,y
中非Number类型的一方使用 ToNumber 函数转化为 Number
类型再进行比较;1
2
3
4
5
6
7
8
9
10// 如果 x 的类型为Number,y 的类型为String
x == ToNumber(y)
// 如果 x 的类型为Boolean,y 的类型为Number
ToNumber(x) == y
// 如果 x 的类型为Boolean,y 的类型为String
ToNumber(x) == ToNumber(y)
例如:
"1" == true // true
"123" == true // false
"0" == false // true
4、 如果 x,y 中有一个为 Object,另外一个是 Number
或 String
,则首先使用 ToPrimitive 函数将Object转化为原始类型,再进行比较。1
2
3
4
5
6
7// 如果 x 的类型为 Number 或 String,y 的类型是 Object
x == ToPrimitive(y)
// 出现一方是Boolean, 另一方是Object
{} == true // 会报错,把前面的{}视为了代码块
true == {} // false
var a = {}
a == true // false
5、 等于运算符并不总是传递的。 例如,可能有两个不同的String对象,每个都表示相同的String值; 每个String对象将被认为与==运算符的String值相等,但是两个String对象不会相等。 例如:1
2
3
4
5new String("a") == "a" and "a" == new String("a")
=> true.
new String("a") == new String("a")
=> false
6、 当 x,y 皆为 Object 类型,则会判断两者是否(指针)指向都一个对象1
2
3
4
5
6var a = {}
a == a
=> true
{} == {} // 此时前者{}不是代码块...e
=> false
关系运算符的精简规则
与相等运算符的规则大致一样,但是一方是Number类型,另一方为其他类型是总是为强制转换Number,例如:
1 | null >= 0 |
ToPrimitive
1 | var ToPrimitive = function(obj,preferredType){ |
++[[]][+[]]+[+[]]==”10”
首先拆分开来描述,它等价于:
1 | ++[[]][+[]] |
第一行与第三行的+[]
可强制转换为 Number 结果为 0
,得出下方结论:
1 | ++[[]][0] |
第一行:[[]][0]
的意思是指获取数组的索引为0的值得出结果:
[[]][0]
返回[]
。根据语言规范,我们说[[]][0] === []
是不正确的,但让我们把这个内部数组称作 a,以避免错误的写法。++[[]][0] == a + 1
, 因为 ++ 的意思是”加一”。- ++[[]][0] === +(a + 1);换句话说,你得到的永远是个数值( +1 并不一定得到的是个数值,但 ++ 一定是)。
同样,我们可以把这一堆代码简化的更清晰。让我们把 a 换回成 [] :
1 | +([] + 1) |
在 JavaScript 里,这也是正确的:[] + 1 === “1”,因为 [] == “” (这相当于一个空的数组的内部元素连接),于是:
1 | +([] + 1) === +("" + 1),并且 |
最后:1
2
3
4
51
+
[0] => "0"
1 + "0" === "10"
null >= 0 返回 true, 而null == 0 || null > 0 返回 false
1、 关系运算符 < > 和 相等运算符 == 并不是一个类别的.
2、 关系运算符,在设计上,总是需要运算元尝试转为一个number . 而相等运算符在设计上,则没有这方面的考虑.
3、 最重要的一点, 不要把 拿 a > b , a == b 的结果 想当然的去和 a >= b 建立联系. 正确的符合最初设计思想的关系是 a > b 与 a >= b是一组 . a == b 和其他相等运算符才是一组. 比如 a === b , a != b, a !== b .
1 | null > 0 // null 尝试转型为number , 则为0 . 所以结果为 false, |
参考
王下邀月熊
The Abstract Equality Comparison Algorithm
Why null >= 0 && null <= 0
but not null == 0
?