JavaScript比较运算符
不论是哪种编程语言,比较运算符都必不可少,无论是JavaScript
还是C
,亦或是Java
,他们的表现形式几乎没有太大的差别:
- 大于号
>
- 小于号
<
- 等于号
==
- 大于等于
>=
- 小于等于
<=
- 不等于
!=
如果学习过其他语言的小伙伴肯定见怪不怪了,在这里,
- 双等号
==
用于相等性检测,使用双等号的目的主要是避免和赋值运算符=
冲突; >=
等价于数学中的≥
;<=
等价于数学中的≤
;!=
等价于数学中的≠
。
比较的结果
所有的运算符都会返回一个结果,比较运算符同样如此,所有比较运算符都会返回Boolean
类型的值:
true
——表示正确、是的、真的等积极意义;false
——表示错误、不是、假的等消极意义;
举例为证:
let a = 1 > 2;
alert(typeof a); // boolean
alert(a); // false
数值之间的比较非常简单,这里不过多赘述。
字符串比较
和数学运算不同,JavaScript
中的字符串也能参与比较。在字符串比大小时,需要参照“字典”顺序进行判定。
如果了解计算机的组成原理,就应该知道,所有的数据都是以二进制编码的形式存在于计算机中的,这些编码遵循一个标准,叫做ASCII
:
ASCII
编码规定了每个符号的编码(‘数字编号’),计算机通过记录这些数字编号描述每个字符,也就是说,在计算机的眼中并不存在字符,它们统一都是数字。
例如字符'A'
对应数字65,字符'a'
对应数字97,如果我们比较二者的大小:
let r = 'A' > 'a';
alert(r); //false
本质上比较的是数字65和97,显然65小于97,所以 'A' > 'a'
返回false
。
如果理解了单个字符的比较规则,字符串的比较就更容易理解了。
字符串的比较本质上是对组成字符串的字符逐个单独的比较,直到分出大小。
举个栗子:
alert('Abc'>'ABC'); //true
alert('Trump' >= 'LaLA'); //true
alert('aaa'=='aaa'); //true
字符串比较算法描述
- 比较首字符大小;
- 如果一方较大(较小),则字符串大于(小于)另一个字符串,结束;
- 否则,比较两字符串的下一个字符大小;
- 重复执行2、3步骤,直到字符串结尾;
- 如果两个字符串同时结束,则相等,否则未结束的字符串更大。
不同类型间的比较
比较不同类型的值时,JavaScript
引擎会尝试将非数字类型转为数字类型,然后判定大小。
举个例子:
let x = '6';
let y = 6;
alert(x == y);//true
如果是Boolean
类型:
alert(true == 1);//true
alert(false == 0);//true
这种特性的出现,得益于JavaScript
完善的隐式转换能力。
但是这种能力并非总是好用的,有些情况下,我们需要严格的判断变量的大小:
例如,我们希望'0'==0
返回的是false
,==
是分辨不了的。
运算符 >、< 、>=、<=
>
、<
、>=
、<=
运算符是比较运算符中规则比较简单,本文称之为基本规则:
基本规则:
- 同类之间直接比较大小;
- 字符串之间按照
ASCII
码表比较大小和长短; - 不同类型之间先转为
Number
,再进行比较; - 不能转为
Number
类型的情况,转为NaN
,NaN
参与的比较都返回false
;
相等性比较 ==、!=
在基本规则的基础上,添加如下规则:
null
和undefined
不发生类型转换;null == undefined
;
null
和nudefined
在参与相等性判断时不发生类型转换:
举个栗子:
alert('' == null) //false
alert(0 == null)//false
alert('' == undefined)//false
alert(0 == undefined)//false
也就是说null
和undefined
除了相互之间相等之外,和其他值均不相等!
!=
表达的是不相等,计算方法同==
一样,举个栗子:
alert('0' != 0) //false
alert(0 != null)//true
alert('' != undefined)//true
alert(null != undefined)//false
严格相等 !== 、===
严格相等运算符===
会将左右两侧的变量直接比较,不进行类型转换,不同类型的数据之间永远不会相等。
比较规则:
- 不同类型返回
false
; - 相同类型直接比较;
alert('0'=== 0);//false
alert(0 === false); //false
alert(null === undefined)//false
我建议在进行相等性检查时,使用严格相等,避免莫名其妙的错误。
比较运算符中的陷阱
null vs undefined
比较null
和undefined
,会发现 >=
和<=
都返回false
,然而,null
却等于undefined
!
alert(null > undefined); //false
alert(null < undefined); //false
alert(null >= undefined); //false
alert(null <= undefined); //false
alert(null == undefined); //true
出现这种现象的原因是,当使用数学比较运算符>
、<
、>=
、<=
时,null
被转型为数字0
,undefined
被转型为NaN
;
而null == undefined
则是JavaScript
的一个特殊规则。
null vs 0
在比较null
和0
时,同样有一个奇怪的现象>=
和<=
会返回true
,而==
反而返回了false
。
alert(null > 0); //false
alert(null < 0); //false
alert(null >= 0); //true
alert(null <= 0); //true
alert(null == 0); //false
出现这种现象的原因是,null
和undefined
参与的相等性比较==
不会发生类型转换,所以 null == 0
返回false
。
在其他比较情形下,null
会被转为数字0
,遵循数学规律。
undefined vs 0
undefined
不论怎么和0
比较都不会返回true
。
alert( undefined > 0 ); // false
alert( undefined < 0 ); // false
alert( undefined >= 0 ); // false
alert( undefined <= 0 ); // false
alert( undefined == 0 ); // false
产生这种现象的原因是,undefined
在转为数字类型时,会变成NaN
。因此不论怎么比较都不会返回true
。
而在相等性比较==
情况下,不发生类型转换,字符不会返回true
。
问题的避免
以上规则虽然并不复杂,但是却容易遗忘,如何有效避免这些暗藏的陷阱呢?只需要遵循以下3个规则:
- 使用
===
进行相等性判断; - 不用
>
、<
、>=
、<=
判断可能为null
或undefined
的变量; - 如果可以的话,在判断之前显式转换类型,并分别处理
null
和undefined
。
重点总结
null
和undefined
参与==
、!=
不发生类型转换;null == undefined
成立;===
和!==
不发生类转换;
课后作业
"3">"29"; //?
undefined == null; //?
undefined === null; //?
null == 0; //?
null === 0; //?
null == ''; //?