“Determining whether two variables are equivalent is one of the most important operations in programming.” (确定两个变量是否相等是编程中最重要的操作之一)
——Nicholas Zakas
JavaScript中作比较有两个方式:严格模式(strict comparison 使用三个等号 ===)和概要模式(abstract comparison 使用两个等号 ==),对于他们的意义和行为,本文做一个归纳。
为了避免舍本逐末,学习任何知识应该先从标准的定义开始,下面是这两种比较方式在ECMA262标准中的定义:
The Strict Equality Comparison Algorithm(严格相等比较算法)
The comparison x === y, where x and y are values, produces true or false. Such a comparison is performed as follows:(判断步骤如下,注意次序)
The Abstract Relational Comparison Algorithm
The comparison x < y, where x and y are values, produces true, false, or undefined (which indicates that at least one operand is NaN). In addition to x and y the algorithm takes a Boolean flag named LeftFirst as a parameter. The flag is used to control the order in which operations with potentially visible side-effects are performed upon x and y. It is necessary because ECMAScript specifies left to right evaluation of expressions. The default value of LeftFirst is true and indicates that the x parameter corresponds to an expression that occurs to the left of the y parameter’s corresponding expression. If LeftFirst is false, the reverse is the case and operations must be performed upon y before x. Such a comparison is performed as follows:(判断步骤如下,注意次序)
通过定义,可以归纳出下面的特点:
根据上面的规则,我们知道:如果在比较时两个变量的类型很重要,就要使用严格比较(===);否则可以使用一般比较(==)。
在JavaScript中,下面的值被当做假(false),除了下面列出的值,都被当做真(true):
分析如下的代码:
1
2
3
4
5
6
7
8
9
10
11
12 |
5==‘5‘
//
true 右边的字符串会被转换为数字,然后进行比较
"1"==true // true true会先转换成数值 1,然后进行比较
//注意
String 对象和 string字符串不同,String对象一般来说很少使用
vara=newString("foo");
varb=newString("foo");
a==b //false
a===b //false
a=="foo" //true
a==="foo"//false |
注意在使用 == 时,在类型不同时,会进行强制类型转换,这个转换的规则十分复杂(上面的特点中有简单的说明,详见 ToPrimitive),不了解规则时,会发现表现十分的奇怪:
1
2
3
4
5
6
7
8
9
10
11 |
‘‘==‘0‘
//false
0==‘‘
//true
0==‘0‘ //true
false==‘false‘ //false
false==‘0‘ //true
false==undefined //false
false==null
//false
null==undefined //true
‘ \t\r\n ‘==0
//true |
通过上面的例子可以看出,== 在传递性(即 a == b, a == c 推出 b == c)上是不可靠的,以上例子中如果使用 ===,结果都会是 false。所以建议除非非常清楚自己想要的,一般尽量使用 === 来进行比较。
下面介绍与判断相等相关的几个知识:
注意下面的代码:
1
2 |
NaN === NaN
//false
!!NaN===!!NaN //true |
我们经常会在代码中看到 !! 运算符,它是一个编程技巧,作用主要是把一个变量或表达式转换为boolean,看下面的代码(均返回 true):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 |
!!false===false
!!true===true
!!0===false
!!parseInt("foo")===false//
NaN 为 false
!!1===true
!!-1===true
!!""===false//空字符串为false
!!"foo"===true //非空字符串都为true
!!"false"===true //非空字符串都为true
!!window.foo===false//undefined为false
!!null===false//null为false
!!{}===true //空对象为true
!![]===true //空数组为true
!!newBoolean(false)===true //这里是个对象
!!Boolean(false)===false
//这里才是boolean值 |
相类似的快速转换类型写法还有下面的两个:
Number(foo) === +foo
String(foo) ===
”+foo
大家在阅读js资料时可能会发现有这样的写法推荐,即变量放在双等号的右边,常量放在左边:
1
2
3
4
5 |
//尽量使用
if(‘0‘==a){......
//不要使用
if(a==‘0‘){...... |
这是“Yoda表示法”,名字来源于《星球大战》的 Yoda 大师。他说话的单词顺序相当奇特,比如:“Backwards it is, yes!”。
这样写主要是防止缺少等号的笔误,比如把 if ( a == ’0′ ) 误写成了 if ( a = ’0′ ),如果采用了常量在前的判断写法,如果把 if ( ’0′ == a ) 误写成了 if ( ’0′ = a ),则会抛出错误(ReferenceError: Invalid left-hand side in assignment)。
一般来说,作为代码书写规范来说,推荐常量在左进行判断的写法。
JavaScript中的两个等号(==)和三个等号(===),布布扣,bubuko.com
JavaScript中的两个等号(==)和三个等号(===)
原文:http://www.cnblogs.com/littleCode/p/3709056.html