type
status
date
slug
summary
tags
category
icon
password
上次编辑时间
Jul 2, 2025 02:22 AM
comment
AI 总结
我们知道,在数学中有很多用于比较大小的运算符。
在 JavaScript 中,它们的编写方式如下:
- 大于 / 小于:
a > b
,a < b
。
- 大于等于 / 小于等于:
a >= b
,a <= b
。
- 检查两个值的相等:
a == b
,请注意双等号==
表示相等性检查,而单等号a = b
表示赋值。
- 检查两个值不相等:不相等在数学中的符号是
≠
,但在 JavaScript 中写成a != b
。
在本文中,我们将进一步了解不同类型的比较,JavaScript 是如何进行比较的,包括一些重要的特殊性。
在文末给出了一些秘诀,帮助你避免 “JavaScript 陷阱”相关的问题。
比较结果为 Boolean 类型
所有比较运算符均返回布尔值:
true
—— 表示“yes(是)”,“correct(正确)”或“the truth(真)”。
false
—— 表示“no(否)”,“wrong(错误)”或“not the truth(非真)”。
示例:
和其他类型的值一样,比较的结果可以被赋值给任意变量:
字符串比较
在比较字符串的大小时,JavaScript 会使用“字典(dictionary)”或“词典(lexicographical)”顺序进行判定。
换言之,字符串是按字符(母)逐个进行比较的。
例如:
字符串的比较算法非常简单:
- 首先比较两个字符串的首位字符大小。
- 如果一方字符较大(或较小),则该字符串大于(或小于)另一个字符串。算法结束。
- 否则,如果两个字符串的首位字符相等,则继续取出两个字符串各自的后一位字符进行比较。
- 重复上述步骤进行比较,直到比较完成某字符串的所有字符为止。
- 如果两个字符串的字符同时用完,那么则判定它们相等,否则未结束(还有未比较的字符)的字符串更大。
在上面的第一个例子中,
'Z' > 'A'
比较在算法的第 1 步就得到了结果。在第二个例子中,字符串
Glow
与 Glee
的比较则需要更多步骤,因为需要逐个字符进行比较:G
和G
相等。
l
和l
相等。
o
比e
大,算法停止,第一个字符串大于第二个。
非真正的字典顺序,而是 Unicode 编码顺序
在上面的算法中,比较大小的逻辑与字典或电话簿中的排序很像,但也不完全相同。
比如说,字符串比较对字母大小写是敏感的。大写的
"A"
并不等于小写的 "a"
。哪一个更大呢?实际上小写的 "a"
更大。这是因为在 JavaScript 使用的内部编码表中(Unicode),小写字母的字符索引值更大。我们会在 字符串 这章讨论更多关于字符串的细节。不同类型间的比较
当对不同类型的值进行比较时,JavaScript 会首先将其转化为数字(number)再判定大小。
例如:
对于布尔类型值,
true
会被转化为 1
、false
转化为 0
。例如:
一个有趣的现象
有时候,以下两种情况会同时发生:
- 若直接比较两个值,其结果是相等的。
- 若把两个值转为布尔值,它们可能得出完全相反的结果,即一个是
true
,一个是false
。
例如:
对于 JavaScript 而言,这种现象其实挺正常的。因为 JavaScript 会把待比较的值转化为数字后再做比较(因此
"0"
变成了 0
)。若只是将一个变量转化为 Boolean
值,则会使用其他的类型转换规则。严格相等
普通的相等性检查
==
存在一个问题,它不能区分出 0
和 false
:也同样无法区分空字符串和
false
:这是因为在比较不同类型的值时,处于相等判断符号
==
两侧的值会先被转化为数字。空字符串和 false
也是如此,转化后它们都为数字 0。如果我们需要区分
0
和 false
,该怎么办?严格相等运算符
===
在进行比较时不会做任何的类型转换。换句话说,如果
a
和 b
属于不同的数据类型,那么 a === b
不会做任何的类型转换而立刻返回 false
。让我们试试:
同样的,与“不相等”符号
!=
类似,“严格不相等”表示为 !==
。严格相等的运算符虽然写起来稍微长一些,但是它能够很清楚地显示代码意图,降低你犯错的可能性。
对 null 和 undefined 进行比较
当使用
null
或 undefined
与其他值进行比较时,其返回结果常常出乎你的意料。当使用严格相等
===
比较二者时它们不相等,因为它们属于不同的类型。当使用非严格相等
==
比较二者时JavaScript 存在一个特殊的规则,会判定它们相等。它们俩就像“一对恋人”,仅仅等于对方而不等于其他任何的值(只在非严格相等下成立)。
当使用数学式或其他比较方法
< > <= >=
时:null/undefined
会被转化为数字:null
被转化为 0
,undefined
被转化为 NaN
。下面让我们看看,这些规则会带来什么有趣的现象。同时更重要的是,我们需要从中学会如何远离这些特性带来的“陷阱”。
奇怪的结果:null vs 0
通过比较
null
和 0 可得:是的,上面的结果完全打破了你对数学的认识。在最后一行代码显示“
null
大于等于 0”的情况下,前两行代码中一定会有一个是正确的,然而事实表明它们的结果都是 false。为什么会出现这种反常结果,这是因为相等性检查
==
和普通比较符 > < >= <=
的代码逻辑是相互独立的。进行值的比较时,null
会被转化为数字,因此它被转化为了 0
。这就是为什么(3)中 null >= 0
返回值是 true,(1)中 null > 0
返回值是 false。另一方面,
undefined
和 null
在相等性检查 ==
中不会进行任何的类型转换,它们有自己独立的比较规则,所以除了它们之间互等外,不会等于任何其他的值。这就解释了为什么(2)中 null == 0
会返回 false。特立独行的 undefined
undefined
不应该被与其他值进行比较:为何它看起来如此厌恶 0?返回值都是 false!
原因如下:
(1)
和(2)
都返回false
是因为undefined
在比较中被转换为了NaN
,而NaN
是一个特殊的数值型值,它与任何值进行比较都会返回false
。
(3)
返回false
是因为这是一个相等性检查,而undefined
只与null
相等,不会与其他值相等。
避免问题
我们为何要研究上述示例?我们需要时刻记得这些古怪的规则吗?不,其实不需要。虽然随着代码写得越来越多,我们对这些规则也都会烂熟于胸,但是我们需要更为可靠的方法来避免潜在的问题:
- 除了严格相等
===
外,其他但凡是有undefined/null
参与的比较,我们都需要格外小心。
- 除非你非常清楚自己在做什么,否则永远不要使用
>= > < <=
去比较一个可能为null/undefined
的变量。对于取值可能是null/undefined
的变量,请按需要分别检查它的取值情况。
总结
- 比较运算符始终返回布尔值。
- 字符串的比较,会按照“词典”顺序逐字符地比较大小。
- 当对不同类型的值进行比较时,它们会先被转化为数字(不包括严格相等检查)再进行比较。
- 在非严格相等
==
下,null
和undefined
相等且各自不等于任何其他的值。
- 在使用
>
或<
进行比较时,需要注意变量可能为null/undefined
的情况。比较好的方法是单独检查变量是否等于null/undefined
。