先看一段代码,执行结果有些奇怪,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

cindy
39 声望1 粉丝