# same
# SameValueNonNumber (opens new window)
这个规范规定比较的值 x 和 y 都不为 Number 类型,规范如下:
- x 的类型不为 Number 类型
- y 的类型与 x 的类型一致
- 如果 x 的类型为 Undefined ,返回 true
- 如果 x 的类型为 Null ,返回 true
- 如果 x 的类型为 String,并且 x 和 y 完全相同的代码单元序列 (相同的长度和相应索引处相同的代码单元) ,则返回 true; 否则返回 false
- 如果 x 的类型为 Boolean ,并且 x 和 y 同为 true 或同为 false ,返回 true,否则返回 false
- 如果 x 的类型为 Symbol ,并且 x 和 y 具有相同的 Symbol 值,返回 true,否则返回 false
- 如果 x 和 y 指向同一个对象,返回 true, 否则返回 false
# Strict Equality Comparison (opens new window)
JavaScript 中的全等(===)遵循这个规范,:
- 如果 x 和 y 的类型不同,返回 false
- 如果 x 的为 Number 类型:
- 如果 x 为 NaN ,返回 false
- 如果 y 为 NaN ,返回 false
- 如果 x 和 y 的数值一致,返回 true
- 如果 x 为 +0 并且 y 为 -0 ,返回 true
- 如果 x 为 -0 并且 y 为 +0 ,返回 true
- 返回 false
- 按照 SameValueNonNumber 的结果返回
# SameValue (opens new window)
内部比较抽象操作 SameValue (x,y) ,其中 x 和 y 是 ECMAScript 语言值,生成 true 或 false。规范如下:
- 如果 x 和 y 的类型不同,返回 false
- 如果 x 的类型为 Number
- 如果 x 为 NaN 并且 y 为 NaN ,返回 true
- 如果 x 为 +0 并且 y 为 -0 ,返回 false
- 如果 x 为 -0 并且 y 为 +0 , 返回 false
- 如果 x 和 y 的数值一致,返回 true
- 返回 false
- 按照 SameValueNonNumber 的结果返回
# SameValueZero (opens new window)
- 如果 x 和 y 的类型不同,返回 false
- 如果 x 的类型为 Number
- 如果 x 为 NaN 并且 y 为 NaN ,返回 true
- 如果 x 为 +0 并且 y 为 -0 ,返回 true
- 如果 x 为 -0 并且 y 为 +0 , 返回 true
- 如果 x 和 y 的数值一致,返回 true
- 返回 false
- 按照 SameValueNonNumber 的结果返回
SameValueZero 与 SameValue 的区别仅在于它对 + 0 和 - 0 的处理
# Abstract Equality Comparison (opens new window)
标准相等操作符 (== and !=)
- 如果 x 和 y 的类型相同,会返回 Strict Equality Comparison 的执行结果
- 如果 x 为 null , y 为 undefined ,返回 true
- 如果 x 为 undefined, y 为 null ,返回 true
- 如果 x 是 Number,y 是 String,则将 y 转为 Number,x y 进行比较,返回比较结果
- 如果 x 是 String,y 是 Number,则将 x 转为 Number,x y 进行比较,返回比较结果
- 如果 x 是 Boolean,则将 x 转为 Number,x y 进行比较,返回比较结果
- 如果 y 是 Boolean,则将 y 转为 Number,x y 进行比较,返回比较结果
- 如果 x 是 String、 Number 或 Symbol,y 是 Object,将 y 转为原始类型,x y 进行比较,返回比较结果
- 如果 x 是 Object,y 是 String、 Number 或 Symbol,将 x 转为原始类型,x y 进行比较,返回比较结果
- 返回 false
# 特别的一点
>
<
>=
<=
并不适用于上述规则
null > 0 // false
null >= 0 // true
那么下一个问题,
null == 0
返回的结果应该是什么
答案是 false
在 null > 0
的判断中, js 尝试将 null
转换为 数字,也就是 0 ,此时 0 > 0
是 false
在 null >= 0
的判断中,也是如此,会转为 0,所以 null >= 0
是 true
但是 null == 0
,并不适用此转换规则
>
<
>=
<=
适用 Abstract Relational Comparison (opens new window) ,简单翻译就是
- 首先,使用 Symbol.ToPrimitive 将对象转换为原始值
- 如果两个值都是字符串,则根据它们所包含的 Unicode码点 的值,将它们作为字符串进行比较。
- 否则 JavaScript 会尝试将非数字类型转换为数值。
- 布尔值 tru e和 false 分别转换为 1 和 0。
- null 被转换为 0
- undefined 被转换为 NaN。
- 字符串根据其包含的值进行转换,如果不包含数值,则转换为 NaN。
- 如果任何一个值是 NaN,运算符返回 false。
- 否则,数值将作为数值进行比较。
# == 和 ===
===
- 如果操作数的类型不同,则返回 false。
- 如果两个操作数都是对象,只有当它们指向同一个对象时才返回 true。
- 如果两个操作数都为 null,或者两个操作数都为 undefined,返回 true。
- 如果两个操作数有任意一个为 NaN,返回 false。
- 否则,比较两个操作数的值:
- 数字类型必须拥有相同的数值。+0 和 -0 会被认为是相同的值。
- 字符串类型必须拥有相同顺序的相同字符。
- 布尔运算符必须同时为 true 或同时为 false。
全等运算符与相等运算符(==)最显著的区别是,如果操作数的类型不同,==
运算符会在比较之前尝试将它们转换为相同的类型
被比较值 B | |||||||
---|---|---|---|---|---|---|---|
Undefined | Null | Number | String | Boolean | Object | ||
被比较值 A | Undefined | true | true | false | false | false | IsFalsy(B) |
Null | true | true | false | false | false | IsFalsy(B) | |
Number | false | false | A === B | A === ToNumber(B) | A=== ToNumber(B) | A== ToPrimitive(B) | |
String | false | false | ToNumber(A) === B | A === B | ToNumber(A) === ToNumber(B) | ToPrimitive(B) == A | |
Boolean | false | false | ToNumber(A) === B | ToNumber(A) === ToNumber(B) | A === B | ToNumber(A) == ToPrimitive(B) | |
Object | false | false | ToPrimitive(A) == B | ToPrimitive(A) == B | ToPrimitive(A) == ToNumber(B) | A === B |