相等,还是不等(3) - 真真假假
入门。
布尔值(boolean)分真(true)和假(false)。而其他类型的变量也可以用来判断真假,比如 JavaScript 中以下值会被当做“假”(falsy values):
- false
- 0 (zero)
- "" (empty string)
- null
- undefined
- NaN (Not A Number)
其他的值则被当做“真”。
PHP 里定义以下为假:
- null // null
- 0 // integer
- 0.0 // float
- "0" // string
- "" // empty string
- false // boolean
- array() // empty array
他们在if
,empty
和isset
的测试中反馈如下:
VALUE if() empty() isset()
-------------------------------------
null false true false
0.0 false true true
"0" false true true
"" false true true
false false true true
array() false true true
EVERYTHING_ELSE true false true
放弃?
0
和空字符串""
相等吗?
Python 说:不等
>>> 0 == ""
False
Java 说:你疯了吧
jshell> 0 == ""
| Error:
| bad operand types for binary operator '=='
| first type: int
| second type: java.lang.String
| 0 == ""
| ^-----^
JavaScript 说:相等,稳稳的
> 0 == ""
true
所以假的和假的都相等?
> null == undefined
true
但又不全是
> "" == undefined
false
> NaN == false
false
而且自己不等于自己
> NaN === NaN
false
这一点 Java 和 Python 也是一样的
jshell> Double.NaN == Double.NaN
$2 ==> false
>>> float('nan') == float('nan')
False
如果 a 和 b 相等,b 和 c 相等,那 a 和 c 也应该相等,对吗?
$a = ''; $b = 0; $c = '0a';
$a == $b; // true
$b == $c; // true
$c == $a; // false!
进阶!
关于 NaN
在做判断的时候 JavaScript 把 NaN 当做 false
> x = NaN ? 'true' : 'false'
'false'
但不是所有语言都支持
jshell> int x = Double.NaN ? 0 : 1;
| Error:
| incompatible types: double cannot be converted to boolean
| int x = Double.NaN ? 0 : 1;
| ^--------^
NaN
就是跟任何值都不相等,包括他自己
jshell> Double.NaN - Double.NaN
$1 ==> NaN
这里不妨把 INFINITY 也拉进来讨论,看来无穷大也是不能用来计算的
jshell> Double.POSITIVE_INFINITY - Double.POSITIVE_INFINITY
$2 ==> NaN
jshell> Double.POSITIVE_INFINITY + Double.POSITIVE_INFINITY
$3 ==> Infinity
jshell> Double.POSITIVE_INFINITY + Double.NEGATIVE_INFINITY
$4 ==> NaN
null
和undefined
算是一组,只有他们两个互相相等
> null == undefined
true
> null == null
true
> undefined == undefined
true
== vs ===
JavaScript 和 PHP 中都提供两种判断相等的方法:==
和===
。
==
只判断值是不是相等,如果等号两侧是不一样的类型,他们会被转换成相同的类型进行比较,所以是不具有传递性的,才会出现上面 a==b,b==c
但 a!=c
的情况。而===
是更严格的比较,既包括类型也包括值,因而是具有传递性的。
> false == 0
true
> false === 0
false
另一组比较
> 1 == '1'
true
> 1 === '1'
false
所以 JavaScript 和 PHP 中要尽量使用三个等号。
此外,在 JavaScript 中,Object,包括 Function Object,只等于它自己:
function factory() {
return (a, b) => a + b;
}
const sum1 = factory();
const sum2 = factory();
sum1(1, 2); // => 3
sum2(1, 2); // => 3
sum1 === sum2; // => false
sum1 === sum1; // => true