比较运算符比较它的操作数并返回一个基于表达式是否为 true
的逻辑值。
比较运算符分为关系运算符(Relational Operators)和等值运算符(Equality Operators)。
===
和 !==
操作符,它们会执行严格的相等和不相等比较。这些运算符不会在检查相等之前转换操作数的类型。下面的表格描述了该示例代码中的各比较运算符。运算符 | 描述 | 返回 true 的示例 |
---|---|---|
大于 > | 左边的操作数大于右边的操作数返回 true | b > a |
大于等于 >= | 左边的操作数大于或等于右边的操作数返回 true | b >= a a >= 1 |
小于 < | 左边的操作数小于右边的操作数返回 true | a < b 1 < 2 |
小于等于 <= | 左边的操作数小于或等于右边的操作数返回 true | a <= b b <= 5 |
运算符 | 描述 | 返回 true 的示例 |
---|---|---|
等于 == | 如果两边操作数相等时返回 true | a == 1 '1' == 2 1 == '1' |
不等于 != | 如果两边操作数不相等时返回 true | a != 2 b != '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);// falseconsole.log([] === []);// falseconsole.log({} === {});// false
当我们访问引用数据类型(对象、数组、函数等等)的值时,首先从栈中获得该对象的 地址指针,然后再从 堆内存 中取得所需的数据。
变量 a
实际保存的是指向堆内存中对象的一个指针,而变量 b
保存的是指向堆内存中的另一个对象的指针,虽然这两个对象的值时一样的,但它们是独立的两个对象,占了两份内存空间,所以它们互不相等。
而当将一个为引用数据类型的值的变量赋值给另一个变量时,即拷贝了前者的内存空间的地址指针,因此它们都指向堆内存中同一个对象。
let x = {}let y = xconsole.log(x === y// true