先看一段代码,执行结果有些奇怪,a>= b 同时 a <= b 但是 a!=b。
var a = function() {};
var b = function() {};
a == b // false
a != b // true
a >= b // true
a <= b // true
这涉及到 js 中操作符引起的类型转换。
全等于(==)
ES 规范中 == 的判断流程为:
1.ReturnIfAbrupt(x)
2.ReturnIfAbrupt(y)
3. 如果 Type(x)与 Type(y)相同,返回 x ===y
4. 如果 x 为 null,y 为 undefined,返回 true
5. 如果 x 为 undefined,y 为 null,返回 true
6. 如果 Type(x)是 Number,Type(y)是 String,返回 x == ToNumber(y)
7. 如果 Type(x)是 String,Type(y)是 Number,返回 ToNumber(x) == y
8. 如果 Type(x)是 Boolean,返回 ToNumber(x) == y
9. 如果 Type(y)是 Boolean,返回 x == ToNumber(y)
10. 如果 Type(x)是 String、Number 或者 Symbol,Type(y)是 Object,返回 x == ToPrimitive(y)
11. 如果 Type(x)是 Object,Type(y)是 String、Number 或者 Symbol,返回 ToPrimitive(x)==y
12. 返回 false
ReturnIfAbrupt 判断参数是否正常值,如有报错,中断执行;Type 函数相当于 typeOf 操作符结果;ToPrimitive 返回参数的原始值,在全等于操作符中返回对象依次尝试调用 valueOf 或者 toString 方法的结果,直到结果为非对象
总结一下就是:
1、如果两侧参数类型相同,使用严格等于比较;
2、null 与 undefined 两两相等;
3、若有布尔类型则转化为数字;
4、字符串和数字比较时把字符串转化为数字,进入 1;
5、Object 类型与 Number、String、Symbol 类型比较时,使用 Object 对象的原始值进行比较
6、其他情况返回 false
在上面代码中 a 和 b 的类型都是“function”,应使用严格等于进行比较,它们有不同的引用并不是同一个值,所以结果为 false
大于、小于(>、<)
大于、小于首先使用 valueOf 方法对左右表达式求原始值,再进行比较。在上面代码中 a、b 调用 valueOf 方法返回的是自身方法字符串,因此 >= 和 <= 都成立。
我们还可以对 a、b 的 valueOf 方法进行重写
a.valueOf=function(){return 1;}
b.valueOf=function(){return 2;}
a > b // false
a < b // true
加、减(+、-)
规则为:
1、先求两侧表达式原始值
2、若其中一个为字符串,返回字符串合并
3、两侧表达式转化为数字类型进行运算
还有一些特殊情况:
Infinity-Infinity // NaN
Infinity+Infinity // Infinity
-Infinity+(-Infinity) // -Infinity
+0+0 // +0
+0+(-0) // +0
-0+(-0) // -0
+5+(-5) // +0