咱们知道,在数学中有不少用于比较大小的运算符:javascript
a > b
,a < b
。a >= b
,a <= b
。a == b
(注意表达式中是两个等号 =
,若写为单个等号 a = b
则表示赋值)。≠
符号,而在 JavaScript 中则经过在赋值符号前加叹号表示:a != b
。和其余操做符同样,比较操做符也会有返回值,返回值为布尔值(Boolean)。html
true
—— 表示“yes(是)”,“correct(正确)”或“the truth(真相)”。false
—— 表示“no(否)”,“wrong(错误)”或“not the truth(非真相)”。示例:java
alert( 2 > 1 ); // true(正确)
alert( 2 == 1 ); // false(错误)
alert( 2 != 1 ); // true(正确)
复制代码
和其余类型的值同样,比较的结果能够被赋值给任意变量:react
let result = 5 > 4; // 把比较的结果赋值给 result
alert( result ); // true
复制代码
在比较字符串的大小时,JavaScript 会使用“字典(dictionary)”或“词典(lexicographical)”顺序进行断定。算法
换言之,字符串是按字符(母)逐个进行比较的。微信
例如:app
alert( 'Z' > 'A' ); // true
alert( 'Glow' > 'Glee' ); // true
alert( 'Bee' > 'Be' ); // true
复制代码
字符串的比较算法很是简单:学习
在上面的例子中,'Z' > 'A'
在算法的第 1 步就获得了返回结果,而字符串 Glow
与 Glee
则继续逐个字符比较:ui
G
和 G
相等。l
和 l
相等。o
比 e
大,算法中止,第一个字符串大于第二个。非真正的字典顺序,而是 Unicode 编码顺序
在上面的算法中,比较大小的逻辑与字典或电话簿中的排序很像,但也不彻底相同。编码
好比说,字符串比较对字母大小写是敏感的。大写的
"A"
并不等于小写的"a"
。哪个更大呢?实际上小写的"a"
更大。这是由于在 JavaScript 使用的内部编码表中(Unicode),小写字母的字符索引值更大。咱们会在 info:string 这章讨论更多关于字符串的细节。
当对不一样类型的值进行比较时,JavaScript 会首先将其转化为数字(number)再断定大小。
例如:
alert( '2' > 1 ); // true,字符串 '2' 会被转化为数字 2
alert( '01' == 1 ); // true,字符串 '01' 会被转化为数字 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 而言,这种现象其实挺正常的。由于 JavaScript 会把待比较的值转化为数字后再作比较(所以
"0"
变成了0
)。若只是将一个变量转化为Boolean
值,则会使用其余的类型转换规则。
普通的相等性检查 ==
存在一个问题,它不能区分出 0
和 false
:
alert( 0 == false ); // true
复制代码
也一样没法区分空字符串和 false
:
alert( '' == false ); // true
复制代码
这是由于在比较不一样类型的值时,处于相等判断符号 ==
两侧的值会先被转化为数字。空字符串和 false
也是如此,转化后它们都为数字 0。
若是咱们须要区分 0
和 false
,该怎么办?
严格相等操做符 ===
在进行比较时不会作任何的类型转换。
换句话说,若是 a
和 b
属于不一样的数据类型,那么 a === b
不会作任何的类型转换而马上返回 false
。
让咱们试试:
alert( 0 === false ); // false,由于被比较值的数据类型不一样
复制代码
一样的,与“不相等”符号 !=
相似,“严格不相等”表示为 !==
。
严格相等的操做符虽然写起来稍微长一些,可是它可以很清楚地显示代码意图,下降你犯错的可能性。
当使用 null
或 undefined
与其余值进行比较时,其返回结果经常出乎你的意料。
当使用严格相等 ===
比较两者时:它们不相等,由于它们属于不一样的类型。
alert( null === undefined ); // false
复制代码
当使用非严格相等 ==
比较两者时:JavaScript 存在一个特殊的规则,会断定它们相等。他们俩就像“一对恋人”,仅仅等于对方而不等于其余任何的值(只在非严格相等下成立)。
alert( null == undefined ); // true
复制代码
当使用数学式或其余比较方法 < > <= >=
时:null/undefined
会被转化为数字。null
被转化为 0
,undefined
被转化为 NaN
。
下面让咱们看看,这些规则会带来什么有趣的现象。同时更重要的是,咱们须要从中学会如何远离这些特性带来的“陷阱”。
经过比较 null
和 0 可得:
alert( null > 0 ); // (1) false
alert( null == 0 ); // (2) false
alert( null >= 0 ); // (3) true
复制代码
是的,上面的结果彻底打破了你对数学的认识。在最后一行代码显示“null
大于等于 0”的状况下,前两行代码中必定会有一个是正确的,然而事实代表它们的结果都是 false。
为何会出现这种反常结果,这是由于相等性检测 ==
和普通比较符 > < >= <=
的代码逻辑是相互独立的。进行值的比较时,null
会被转化为数字,所以它被转化为了 0
。这就是为何(3)中 null >= 0
返回值是 true,(1)中 null > 0
返回值是 false。
另外一方面,undefined
和 null
在相等性检测 ==
中不会进行任何的类型转换,它们有本身独立的比较规则,因此除了它们之间互等外,不会等于任何其余的值。这就解释了为何(2)中 null == 0
会返回 false。
undefined
不该该被与其余值进行比较:
alert( undefined > 0 ); // false (1)
alert( undefined < 0 ); // false (2)
alert( undefined == 0 ); // false (3)
复制代码
为什么它看起来如此厌恶 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
。先本身作题目再看答案。
重要程度:⭐️⭐️⭐️⭐️⭐️
如下表达式的执行结果是?
5 > 4
"apple" > "pineapple"
"2" > "12"
undefined == null
undefined === null
null == "\n0\n"
null === +"\n0\n"
复制代码
5 > 4 → true
"apple" > "pineapple" → false
"2" > "12" → true
undefined == null → true
undefined === null → false
null == "\n0\n" → false
null === +"\n0\n" → false
复制代码
结果的缘由:
"2"
大于 "1"
。null
只与 undefined
互等。null
只与 undefined
相等。现代 JavaScript 教程:开源的现代 JavaScript 从入门到进阶的优质教程。React 官方文档推荐,与 MDN 并列的 JavaScript 学习教程。
在线免费阅读:zh.javascript.info
扫描下方二维码,关注微信公众号「技术漫谈」,订阅更多精彩内容。