js 对象>=比较时为true的奇葩现象,求指导,为什么,有相关规范吗?

两个对象比较为什么 >=,<=的时候会是true?

a = {a:1};
b = {b:1};
console.log("a == b : ", a==b);   // a == b :  false
console.log("a > b : ", a>b);     // a > b :  false
console.log("a < b : ", a<b);     // a < b :  false
console.log("a >= b : ", a>=b);   // a >= b :  true
console.log("a <= b : ", a<=b);   // a <= b :  true
阅读 3.6k
5 个回答

首先强烈推荐一本书《你不知道的Javascript》

书中有讲到这个问题:移步github

也就是说,首先:

  1. 如果'<'或者'>'比较的两个值都是string的话,就会在字符上进行简单的字典顺序(自然的字母顺序)比较
  2. 如果'<'或者'>'比较的两个值都是number的话,就直接数值比较了
  3. 如果非1,2。则首先在两个值上调用ToPrimitive强制转换,如果两个调用的返回值之一不是string,那么就使用ToNumber操作规则将这两个值强制转换为number值,并进行数字的比较。

所以:

a = {a:1}; // ToPrimitive => "[object Object]"
b = {b:1}; // ToPrimitive => "[object Object]"

a > b // false, 在字典顺序上[object Object]不大于[object Object]
a < b // false, 在字典顺序上[object Object]不小于[object Object]
a == b // false, 对象"=="比较的是所持的引用是否相同
a <= b // true, 语言规范说,对于a <= b,它实际上首先对b < a求值,然后反转那个结
果。因为b < a也是false,所以a <= b的结果为true。

javascript里面相等(==,===)和比较(> , < , >=, <=)是两种不同的操作,前面的叫做相等操作符,后面的叫做关系操作符,他们的规则是不一样的。

我猜题主觉得奇葩,是因为如果a >= b和a <= b都是true,那么逻辑上了来说就是a等于b,但是a == b却是false。这里是因为>=(包括>,<,<=)和==是不同的操作符,使用的不同规则。== 为什么是false大家都知道,就不说了。

下面的内容出自于《javascript高级程序设计》:
当关系操作符的操作数是对象时,先调用valueOf方法,用得到的结果进行比较;若没有valueOf方法,调用toString方法,用得到的结果进行比较

图片描述
不过我感觉好像也不太对,因为对象的valueOf方法返回对象本身valueOf__MDN,所以我觉得是调用的toString方法,所以就转化成了"[object Object]" >= "[object Object]"和"[object Object]" <= "[object Object]"。所以都是true

Number({})的结果是NaN
NaN又是一个不等于自己的特殊常量

比较运算符
引用数据类型转化为基础数据类型,先 valueOf 后 toString。得:"[object Object]" >= "[object Object]"。两个字符串正好都一样,就返回true了。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题