宽松相等(==)和严格相等(===)
在看到这个知识点之前,我也是和大部分程序员一样,错误的认识了'=='和'==='
相同点:都用来判断两个值是否'相等'
不同点:
1、理解上的不同点
一般理解(是错误的理解,虽然很多博客和书籍都是这样解释的,具体原因就是下面性能的分析):
'==':检查值是否相等
'===':检查值和类型是否相等
精确的理解:
'==':允许在相等比较中进行强制类型转换
'===':不允许进行强制类型转换
2、性能上的不同点
为什么说一般的理解是错误的不正确的,是因为在性能上来分析,
在一般的理解方式中,‘===’做的是事情更多,不仅是要判读值是否相等还要判断类型是否相等
但是事实并不是这样的,在精确的理解中,'=='做的事情是更多的,因为值得类型要是不相等还需要进行强制类型转换
如果进行比较的两个值类型相同,则'=='和'==='使用相同的算法,所以除了javascript引擎实现的细微差别之外,他们之间没有 任何的不同
如果两个值的类型不同,我们就需要考虑有没有强制类型转换的必要,有就用'==',没有就用'===',不用在乎性能,因为强制 类型的转换确实需要多花点时间,但仅仅是微秒级别(百万分之一秒)的差别
3、比较时类型转换的规则
3.1、字符串和数字之间的相等比较
var a = 12
var b = '12'
console.log(a == b) // true
console.log(a === b) // false
因为没有强制类型的转换,所以 === 会输出false
在类型不同的时候,是a从数字转换成字符串,还是b从字符串转换成数字
ES5中数字和字符串==时规则:
(1)如果Type(x)是数字,Type(y)是字符串,则返回 x == ToNumber(y)的结果
(1)如果Type(x)是字符串,Type(y)是数字,则返回 ToNumber(x) == y 的结果
其实就是,当字符串和数字进行相等的比较的时候,永远都是字符串进行转换成数字进行比较
3.2、其他类型和布尔之间的相等比较
// 数字和布尔
var a = 12
var b = true
var c = false
console.log(a == b) // false
console.log(a == c) // false
// 字符串和布尔
var a = '12'
var b = true
var c = false
console.log(a == b) // false
console.log(a == c) // false
我们都知道42是真值,但是和布尔进行比较的时候,确不是正确的,那是因为'=='进行比较的时候,转换规则的原因
ES5中布尔和其他类型==时规则:
(1)如果Type(x)是布尔类型·,返回 ToNumber(x) == y 的结果
(1)如果Type(y)是布尔类型,则返回 x == ToNumber(y) 的结果
就是任何类型和布尔进行宽松相等的话,都是布尔值进行类型转换,true的话就会转换成1,false的话就会转换成0,然后再进行比较(===严格相等更不能成立,所以没有讨论的必要了)
在上面例子一中:
a == b时:b布尔类型转换成数字类型,为1,所以最终比较时 12 == 1,即返回false
a == c时,c布尔类型转换成数字类型,为0,所以最终比较时 12 == 0,也会返回false
在上面的例子二中:
a == b时:a字符串类型转换成数字类型,为12,b布尔类型转换成数字类型,为1,所以最终比较时 12 == 1,即返回false
a == c时,a字符串类型转换成数字类型,为12,c布尔类型转换成数字类型,为0,所以最终比较时 12 == 0,也会返回false
3.3、null和undefined之间的相等比较
在之前的介绍NaN的那篇文章中,也说过了null == null,undefined == undefined
ES5中null和undefined==时规则:
(1)如果x是null,y是undefined,则结果是true
(1)如果x是undefined,y是null,则结果是true
即在 == 中null和undefined是相等的(它们也是与其自身相等的),除此之外其他值都不存在这种情况
也就是说 在 == 中 null和undefined是一回事,可以进行隐式强制转换
var a = null
var b
console.log(a==b) // true
console.log(a==a) // true
console.log(b==b) // true
null和undefined之间的强制转换是绝对可靠的,可以通过这种方式将null和undefined做等价值处理比较好
例如:
(1)var a = dosomething
if (a == null) {
// ...
}
条件判断a == null仅在dosomething返回null和undefined时才成立,除此之外均不成立
(2)这种是比较的繁琐的写法,效果是一样的
var a = dosomething
if (a == null || a == undefined) {
// ...
}
注:'=='和'==='都会检查操作数的类型,区别在于操作数不同时它们的处理方式不同