1 Truthy & Falsey
javascript可以接收一个不是Boolean的变量作为判定条件。所以,单纯的true和false不足以描述到底判定条件满足不满足了。 这时候就需要Truthy
& Falsey
来判定。
在判断条件里,被判定为true
的就是Truthy
。 被判定为false
的就是Falsey
.
Falsey: undefined
, null
, NaN
, 0, ''(空字符串)
, 还有false
。
Truthy: 除了Falsey之外的所有值。
判定语句用法:
if(something) {} else {} //
这里的something可能是
1. variable | !variable
2. x >= y | x < = y | x > y | x < y
3. x === y | x == y | x !== y | x != y
或者是上面三种的组合。
这些都是常用的,就不多说了,只说容易坑的。先来个简单的测试方法:
function testTruthy(arg){
if(arg){
console.log(JSON.stringify(arg) + ' is Truthy');
return true;
}else{
console.log(JSON.stringify(arg) + ' is Falsey');
return false;
}
}
testTruthy(something)
如果something
是Truthy
就会打印 something is Truthy
。 如果something
是Falsey
就会打印 something is Falsey
2 具体实例
2.1 variable 或者 !variable
这个比较简单,如果variable是 undefined
, null
, NaN
, 0, ''(空字符串)
, 还有false
之一。
testTruthy(variable) => false
除了以上这几种情况:
testTruthy(variable) => true
重要的事情说三遍。
除了上面Falsey情况全部返回true
除了上面Falsey情况全部返回true
除了上面Falsey情况全部返回true
2.2 大于或者小于
直接来例子2-2-1:
String比大小的时候是从第一位开始一位一位往后比的。 相关问题:array.sort()为啥排不对。
2.3 相等或者不相等
javascript里有两种比较 ===
或者 ==
。
MDN里面的说法:
A strict comparison (e.g., ===) is only true if the operands are of the same type and the contents match.
The more commonly-used abstract comparison (e.g. ==) converts the operands to the same type before making the comparison.
三个等号是在类型和内容都相同的时候才是true
两个等号会先把两边的转化成相同类型,然后比较。
三个等号没啥疑问,但是这个两个等号的就有很多问题了。
先看一个例子2-3-1
我还能说啥?
有一个详细的解释如何对比==
在EMCA 11.9.3
-
在
0==[]
里面,用到了下面两个规则:- If Type(x) is Object and Type(y) is either String or Number, return the result of the comparison ToPrimitive(x) == y.
- If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).
其中
[]
是一个object。 obejct 的ToPrimitive是直接用到了defaultValue。 然后用到了toString
[].toString() // ''
所以根据第九条规则,
0==[]
就相当于0==''
再看第四条,数字和字符串的对比比较的是数字和ToNumber(字符串)。
在ToNumber的规则里,空字符串返回的是0
所以,0==''
返回的是true。 所以0==[]
返回的是true。 -
再看
0=='0'
同样根据上述第四条,比较的是0 和ToNumber('0')
,ToNumber('0')
返回的是0。
所以0=='0'
返回的是true。 -
最后看
'0'==[]
.
根据上述第九条,'0'==[]
就相当于'0'==''
。
两个string相比,真没啥好说的了。所以"0"==[]
返回false。
再看一个例子2-3-2:
所以。。。。空的array到底是个什么鬼?
我们回去看==
在EMCA 11.9.3的解释:
- If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
ToNumber(false)
是0
所以比较的是 [] == 0
现在问题就回到了上面的例子2-3-1。 所以 [] == false
返回true
但是,当把[]
放进判定条件的时候, 请翻到上面2.1大声念出来最后三句话。
看最后一个空array的例子2-3-3:
没错,刚才说了半天ToNumber
和ToPrimitive
, 这里就不好使了!
再回去看第九条: 当一边是object另一边是string或者number的时候,才会用ToPrimitive
转化[]
。
但2-2-2的例子一边是Boolean,另一边是object。
再回去看第六条: 当一边是Boolean的时候,另一边不管是啥,都用ToNumber()转化这个Boolean。所以,其实看上去右边是个Boolean,其实是个number。
所以[] == []
既不满足第六条,也不满足第九条。实际上不满足EMCA 11.9.3描述的任何一条,最后到了第十条:
- Return false
再看一个其他例子2-3-4:
其实也没啥可以大惊小怪的了。。。。
还有空string 例子2-3-5:
空string本身是falsey的,但是str是用new
创造出来的。在OOP中,有了new
就有了object
. 所以此时str其实是一个String类型的Object。所以是Truthy的。
还有, {}到底做错什么了?2-3-6:
如果要比较object,只能先赋值给某变量,然后再比较。
虽然已经是常识,但是还是要啰嗦一下: object直接比较的话永远是不想等的。
最后, 有个特殊的存在NaN 例子2-3-7:
这几个Falsey之间有几个会互相 ==。 但是,NaN是个不一样的存在,它不等于任何一个。甚至不等于它自己。