我们从数学中知道许多比较运算符。 比较运算符(关系运算符)是两个数据进行比较时所使用的运算符,比较运算后,会返回一个布尔值(true/false)作为比较运算的结果。
在 JavaScript 中,它们的写法如下:
-
大于/小于:a > b,a < b。
-
大于/小于等于:a >= b,a <= b。
-
等于:a == b,请注意双等号 == 表示相等比较,而单等号 a = b 表示赋值。
-
不等于:在数学中记作 ≠,但在 JavaScript 中写作 a != b。
在本文中,我们将进一步了解不同类型的比较、JavaScript 是如何进行这些比较的,以及其中一些重要的特殊之处。
最后,你会看到一个很好的方法来避免与 “JavaScript 怪癖” 相关的问题。

下表显示了 JavaScript 的比较运算符:
Operator | 意义 |
---|---|
< | 少于 |
> | 大于 |
<= | 小于或等于 |
>= | 大于或等于 |
== | 等于 |
!= | 不等于 |
比较运算符返回一个布尔值,指示比较是否为真。
比较运算符的结果是布尔值
所有比较运算符的返回值都是布尔值:
-
true —— 表示 “是”、“正确” 或 “真实”。
-
false —— 表示 “否”、“错误” 或 “不真实”。
例如:
alert( 2 > 1 ); // true (correct) alert( 2 == 1 ); // false (wrong) alert( 2 != 1 ); // true (correct)
比较的结果可以像任何值一样被赋值给变量:
let result = 5 > 4; // assign the result of the comparison alert( result ); // true
比较运算符采用两个值。如果值的类型不可比较,则比较运算符会根据特定规则将它们转换为可比较类型的值。
字符串比较
为了判断一个字符串是否大于另一个,JavaScript 使用所谓的“字典顺序”或“按字母顺序”的方式,JavaScript 将字符串的字符 ASCII 值逐一进行数字比较。
换句话说,字符串是逐字符进行比较的。
例如:
alert( 'Z' > 'A' ); // true alert( 'Glow' > 'Glee' ); // true alert( 'Bee' > 'Be' ); // true
比较两个字符串的算法很简单:
-
比较两个字符串的第一个字符。
-
如果第一个字符串的第一个字符大于(或小于)另一个字符串的对应字符,那么第一个字符串就大于(或小于)第二个字符串。比较结束。
-
否则,如果两个字符串的第一个字符相同,就以相同的方式比较第二个字符。
-
重复这个过程,直到其中一个字符串结束。
-
如果两个字符串同时结束且长度相同,则它们相等。否则,较长的字符串更大。
在上面的第一个例子中,比较 'Z' > 'A'
在第一步就得出了结果。
而第二个比较 'Glow'
和 'Glee'
需要更多步骤,因为字符串是逐个字符比较的:
-
G 和 G 相同。
-
l 和 l 相同。
-
o 大于 e。到此为止,第一个字符串较大。
不是实际的字典顺序,而是 Unicode 顺序
上面提到的比较算法大致类似于字典或电话簿中使用的顺序,但并不完全相同。
例如,大小写是有区别的。大写字母 “A” 不等于小写字母 “a”。那哪个更大呢?是小写的 “a”。为什么?因为在 JavaScript 使用的内部编码表(Unicode)中,小写字符的索引更大。我们将在后面的“字符串”章节中回到这个话题,讲解具体细节和影响。
不同数据类型的比较
当比较不同类型的值时,JavaScript 会将它们转换为数字。
例如:
alert( '2' > 1 ); // true, string '2' becomes a number 2 alert( '01' == 1 ); // true, string '01' becomes a number 1
对于布尔值,true 会被转换为 1,false 会被转换为 0。
例如:
alert( true == 1 ); // true alert( false == 0 ); // true
有趣的结果
有时候可能会出现这样的情况:
-
两个值是相等的;
-
但其中一个的布尔值上为 true,另一个为 false。
例如:
let a = 0; alert( Boolean(a) ); // false let b = "0"; alert( Boolean(b) ); // true alert(a == b); // true!
从 JavaScript 的角度来看,这个结果是完全正常的。相等比较会使用数字转换(因此 “0” 会变成 0),而显式的布尔转换则使用的是另一套规则。
严格相等运算符 (全等运算符)
普通的相等检查 ==
存在一个问题。它无法区分 0 和 false:
alert( 0 == false ); // true
空字符串也会出现同样的问题:
alert( '' == false ); // true
这是因为不同类型的操作数在相等运算符 ==
中会被转换为数字。空字符串就像 false 一样,会变成 0。
如果我们想区分 0 和 false,该怎么办呢?
严格相等运算符 ===
会在不进行类型转换的情况下检查相等性。
换句话说,如果 a 和 b 类型不同,那么 a === b 会直接返回 false,而不会尝试进行类型转换。
我们试试看:
alert( 0 === false ); // false, because the types are different
严格等于 === 和不严格等于 !==
除了上面的比较运算符,JavaScript 还提供了严格等于 ===
和非严格等于 !==
运算符。
Operator | 意义 |
---|---|
=== | 严格相等 |
!== | 不严格相等 |
严格等于和不严格等于运算符的行为类似于等于和不等于运算符,只是它们在比较之前不转换值。
还有一个“严格不等于”运算符 !==
,它与 !=
类似。
严格相等运算符虽然写起来稍微长一点,但它能明确表示正在发生什么,并且减少了出错的可能性。等于 == 运算符 和 全等 === 运算符,==运算符 会默认转换数据类型,当数字类型和字符类型相比较时,会自动将字符类型转换成数字类型进行比较,只要求值相等就可以了;而 全等 === 运算符,要求两边的值 和 数据类型,必须完全一样才可以时 true。
比较 null 和 undefined
在 JavaScript 中,null
等于 undefined
。这意味着下面的表达式返回true
.
当 null 或 undefined 与其他值进行比较时,会出现一些非直观的行为。
对于严格相等检查 ===
:
-
这些值是不同的,因为它们各自是不同的类型。
alert( null === undefined ); // false
于非严格相等检查 ==
:
-
有一个特殊规则。这两个值是“一对甜蜜的情侣”:它们彼此相等(在
==
的意义上),但与其他任何值都不相等。
alert( null == undefined ); // true
对于数学和其他比较运算符 < > <= >=
:
-
null
和undefined
会被转换为数字:null
变成 0,而undefined
变成NaN
。
现在,让我们看看应用这些规则时会发生的一些有趣的事情。更重要的是,如何避免在这些规则中陷入陷阱。
奇怪的结果:null 与 0 的比较
让我们将 null
与 0 进行比较:
alert( null > 0 ); // (1) false alert( null == 0 ); // (2) false alert( null >= 0 ); // (3) true
从数学角度来看,这很奇怪。最后的结果表示“null 大于或等于零”,所以在上述某个比较中它必须是正确的,但它们实际上都是 false。
原因在于,相等检查 ==
和比较运算符 > < >= <=
的工作方式不同。比较运算符会将 null
转换为数字,将其视为 0。这就是为什么 (3) null >= 0
为 true,而 (1) null > 0
为 false。
另一方面,null
和 undefined
的相等检查 ==
被定义为在没有任何转换的情况下,它们相互相等,但不与任何其他值相等。这就是为什么 (2) null == 0
为 false。
无法比较的 undefined
undefined
的值不应与其他值进行比较:
alert( undefined > 0 ); // false (1) alert( undefined < 0 ); // false (2) alert( undefined == 0 ); // false (3)
为什么它总是和零不合?总是返回 false!
我们得到这些结果是因为:
-
比较 (1) 和 (2) 返回 false,因为
undefined
会被转换为NaN
,而NaN
是一个特殊的数字值,对于所有比较都返回 false。 -
相等检查 (3) 返回 false,因为
undefined
只与null
、undefined
相等,和其他任何值都不相等。
避免问题
为什么我们要讲这些例子?我们是否应该时刻记住这些特殊情况?其实并不需要。实际上,这些棘手的情况会随着时间的推移逐渐变得熟悉,但有一个可靠的方法可以避免遇到这些问题:
-
除了严格相等
===
外,任何与undefined
/null
的比较都要格外小心。 -
不要在一个可能是
null
/undefined
的变量上使用比较运算符>= > < <=
,除非你非常确定自己在做什么。如果一个变量可能具有这些值,请单独检查它们。
总结:
-
比较运算符返回布尔值。
-
字符串按字母顺序逐个字符进行比较,采用“字典”顺序。
-
当比较不同类型的值时,它们会被转换为数字(严格相等检查除外)。
-
值
null
和undefined
彼此相等==
,但不等于其他任何值。 -
当使用类似
>
或<
的比较运算符时,若变量可能为null
/undefined
,需要格外小心。最好单独检查null
/undefined
。