引言
一般语言比较两个值相等使用‘==’,JavaScript也是如此,但是作为一门弱类型语言。有其天生缺陷,并不能完全比较,所以JavaScript还有个严格相等‘===’
一般来说通常而言,==检查值是否相等,===检查值和类型是否都相等。其实
宽松相等(==)
宽松相等使用起来方便简洁,这是因为当比较不同类型的值时其背后为我们做了隐式强制类型转换
字符串和数字之间的相等比较
var a = 42;
var b = '42';
a === b; //false
a == b; //true
根据ES5规范11.9.3.4-5的定义:
- 如果Type(x)是数字,Type(y)是字符串时,则返回 x == ToNumber(y) 的结果
- 如果Type(x)是字符串,Type(y)是数字时,则返回 ToNumber(x) == y 的结果
其他类型和布尔类型之间的相等比较
var a = '42';
var b = true;
a == b; //false
我们都知道'42'是个真值,但为啥没有相等呢?
根据ES5规范11.9.3.6-7的定义:
- 如果Type(x)是布尔类型,则返回 ToNumber(x) == y 的结果
- 如果Type(y)是布尔类型时,则返回 x == ToNumber(y) 的结果
因此这个问题中,'42'是真值没错,但不是‘42’转化为布尔类型,而是true转换为1。
null和undefined之间的相等比较
var a = null;
var b;
a == b; //true
a == null; //true
b == null; //true
a == false; //false
b == false; //false
a == ''; //false
b == ''; //false
a == 0; //false
b == 0; //false
根据ES5规范11.9.3.2-3的定义:
- 如果x为null,y为undefined,则结果为true
- 如果x为undefined,y为null,则结果为true
在==中null和undefined相等(它们也与其自身相等),除此之外其他值都不和它们两个相等。这也就是说,
对象和非对象之间的相等比较
var a = 42;
var b = [42];
a == b; //true
根据ES5规范11.9.3.8-9的定义:
- 如果Type(x)是字符串或数字,Type(y)是对象,则返回 x == ToPrimitive(y)的结果
- 如果Type(y)是字符串或数字,Type(x)是对象,则返回 ToPrimitive(x) == y的结果
上例中[42]首先调用ToPrimitive抽象操作,返回'42',变成‘42’ == 42,然后又变成 42 == 42,最后二者相等