比较运算符
比较运算符比较它的操作数并返回一个基于表达式是否为 true 的逻辑值。
比较运算符分为关系运算符(Relational Operators)和等值运算符(Equality Operators)。
- 操作数可以是数字,字符串,逻辑,对象值。
- 字符串比较是基于标准的字典顺序,使用 Unicode 值。
- 在多数情况下,如果两个操作数不是相同的类型, JavaScript 会尝试转换它们为恰当的类型来比较。这种行为通常发生在数字作为操作数的比较。
- 类型转换的例外是使用 ===和!==操作符,它们会执行严格的相等和不相等比较。这些运算符不会在检查相等之前转换操作数的类型。下面的表格描述了该示例代码中的各比较运算符。
关系运算符
| 运算符 | 描述 | 返回 true的示例 | 
|---|---|---|
| 大于 > | 左边的操作数大于右边的操作数返回 true | b > a | 
| 大于等于 >= | 左边的操作数大于或等于右边的操作数返回 true | b >= aa >= 1 | 
| 小于 < | 左边的操作数小于右边的操作数返回 true | a < b1 < 2 | 
| 小于等于 <= | 左边的操作数小于或等于右边的操作数返回 true | a <= bb <= 5 | 
等值运算符
| 运算符 | 描述 | 返回 true的示例 | 
|---|---|---|
| 等于 == | 如果两边操作数相等时返回 true | a == 1'1' == 21 == '1' | 
| 不等于 != | 如果两边操作数不相等时返回 true | a != 2b != '1' | 
| 全等 === | 两边操作数相等且类型相同时返回 true | a === 1 | 
| 不全等 !== | 两边操作数不相等或类型不同时返回 true | a !== '1'1 !== '1' | 
抽象相等比较算法
- 若 Type(x) 与 Type(y) 相同,则
- 若 Type(x) 为 Undefined,返回
true- 若 Type(x) 为 Null,返回
true- 若 Type(x) 为 Number,则
- 若 x 为 NaN,返回
false- 若 y 为 NaN,返回
false- 若 x 与 y 为相等数值,返回
true- 若 x 为 +0 且 y 为 -0,返回
true- 若 x 为 -0 且 y 为 +0,返回
true- 返回
false- 若 Type(x) 为 String
- 当 x 和 y 为完全相同的字符序列(长度相等且相同字符在相同位置)时返回
true- 否则,返回
false- 若 Type(x) 为 Boolean
- 当 x 和 y 为同为
true或者同为false时返回true- 否则,返回
false- 当 x 和 y 为引用用一对象时返回
true。否则,返回false。- 若 x 为 null 且 y 为 undefined,返回
true- 若 x 为 undefined 且 y 为 null,返回
true- 若 Type(x) 为 Number 且 Type(y) 为 String,返回比较
x == ToNumber(y)的结果- 若 Type(x) 为 String 且 Type(y) 为 Number,返回比较
ToNumber(x) == y的结果- 若 Type(x) 为 Boolean,返回比较
ToNumber(x) == y的结果- 若 Type(y) 为 Boolean,返回比较
x == ToNumber(y)的结果- 若 Type(x) 为 String 或 Number,且 Type(y) 为 Object,返回比较
x == ToPrimitive(y)的结果- 若 Type(x) 为 Object 且 Type(y) 为 String 或 Number,返回比较
ToPrimitive(x) == y的结果- 返回
false
按以上相等之定义:
- 字符串比较可以按这种方式强制执行:'' + a == '' + b
- 数值比较可以按这种方式强制执行:+a == +b
- 布尔值比较可以按这种方式强制执行:!a == !b
等值比较操作保证以下不变:
- A !== B等价于- !(A == B)
- A == B等价于- B == A,除了 A 与 B 的执行顺序。
相等运算符不总是传递的。例如,两个不同的 String 对象,都表示相同的字符串值;== 运算符认为每个 String 对象都与字符串值相等,但是两个字符串对象互不相等。
- new String('a') == 'a'和- 'a' == new String('a')皆为- true
- new String('a') == new String('a')为- false
字符串比较使用的方式是简单地检测字符编码单元序列是否相同。不会做更复杂的、基于语义的字符或者字符串相等的定义以及 Unicode 规范中定义的 Collating Order。所以 Unicode 标准中认为相等的 String 值可能被检测为不等。实际上这一算法认为两个字符串已经是经过规范化的形式。
引用数据类型间比较
const a = function() {};
const b = function() {};
console.log(a === b);
// false
console.log([] === []);
// false
console.log({} === {});
// false
当我们访问引用数据类型(对象、数组、函数等等)的值时,首先从栈中获得该对象的 地址指针,然后再从 堆内存 中取得所需的数据。
变量 a 实际保存的是指向堆内存中对象的一个指针,而变量 b 保存的是指向堆内存中的另一个对象的指针,虽然这两个对象的值时一样的,但它们是独立的两个对象,占了两份内存空间,所以它们互不相等。
而当将一个为引用数据类型的值的变量赋值给另一个变量时,即拷贝了前者的内存空间的地址指针,因此它们都指向堆内存中同一个对象。
let x = {}
let y = x
console.log(x === y
// true