一、相等和不相等(==和!=)
先转换再比较
在转换不同的数据类型时,相等和不相等操作符遵循下列基本规则:
- 如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值——false转换为0,true转换为1;
- 如果一个操作数是字符串,另一个数是数值,在比较相等性之前先将字符串转换为数值;
- 如果一个操作数是对象,另一个操作数不是,则调用对象的ToPrimitive()方法,用得到的基本类型值按照前面的规则进行比较;
- null和undefined是相等的;
- 要比较相等性之前,不能将null和undefined转换成其他任何值;
- 如果有一个操作数是NaN,则相等操作符返回false,而不相等操作符返回true。
- 如果两个操作数都是对象,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,则相等操作符返回true;否则,返回false。
ToPrimitive()运算符把其值参数转换为非对象类型。依下表。
JS引擎内部转换为原始值ToPrimitive(obj,preferredType)函数接受两个参数,第一个obj为被转换的对象,第二个preferredType为希望转换成的类型(默认为空,接受的值为Number或String)
在执行ToPrimitive(obj,preferredType)时如果第二个参数为空并且obj为Date的实例时,此时preferredType会被设置为String,其他情况下preferredType都会被设置为Number如果preferredType为Number,ToPrimitive执行过程如下:
- 如果obj为原始值,直接返回;
- 否则调用 obj.valueOf(),如果执行结果是原始值,返回之;
- 否则调用 obj.toString(),如果执行结果是原始值,返回之;
- 否则抛异常。
如果preferredType为String,将上面的第2步和第3步调换,即:
- 如果obj为原始值,直接返回;
- 否则调用 obj.toString(),如果执行结果是原始值,返回之;
- 否则调用 obj.valueOf(),如果执行结果是原始值,返回之;
- 否则抛异常。
原始值即['Null','Undefined','String','Boolean','Number']五种基本数据类型之一。
二、特殊情况的比较结果
null == undefined //true
NaN == NaN //false
NaN != NaN //true
false == 0 //true
true == 1 //true
undefined == 0 //false
null == 0 //false
[] == false //true
[] == ![] //true
[] == 0 //true
'' == false //true
注意:
{} == []
会产生一个解析错误:
SyntaxError: Unexpected token ==
{} 在这里并不是一个空对象,解析器把它当作了一个“代码块”,
因此出现了解析错误,如果把它解析为空对象,需要添加小括号。
({}) == {}; //false
三、逻辑非操作符(!)
逻辑非操作符遵循下列规则:
- 如果操作数是一个对象,返回false;
- 如果操作数是一个空字符串,返回true;
- 如果操作数是一个非空字符串,返回false;
- 如果操作数是数值0,返回true;
- 如果操作数是任意非0数值(包括Infinity),返回false;
- 如果操作数是null,返回true;
- 如果操作数是NaA,返回true;
- 如果操作数是undefined,返回true。