我创建了两个新对象:
var a = new Object();
var b = new Object();
在比较之后,我得到了那些结果:
var a = new Object();
var b = new Object();
console.log(a == b); //false
console.log(a > b); //false
console.log(b > a); //false
console.log(a >= b); //true
console.log(b >= a); //true
请解释一下这是怎么发生的?
答案 0 :(得分:44)
与==
或!=
(或===
或!==
)相比较的对象引用会根据它们是否引用同一对象进行比较。如果是这样,他们是平等的;如果没有,他们就不平等。
但关系比较运算符(>
,<
,>=
和<=
)不会比较引用,它们将操作数强制转换为可以比较:数字或字符串。
对于new Object()
,强制最终会创建一个字符串:"[object Object]"
。当然,"[object Object]" >= "[object Object]"
是正确的,因为它们是平等的。
所以实际上,你实际做的是:
console.log(a == b); //false
console.log(String(a) > String(b)); //false
console.log(String(b) > String(a)); //false
console.log(String(a) >= String(b)); //true
console.log(String(b) >= String(a)); //true
...但请注意,其他对象类型的强制方式不同,因为对象可以通过实现/覆盖valueOf
来选择它们在这种情况下强制执行的方式(规范在字符串上优先使用数字)。例如,如果另一个操作数也可以强制转换为数字,则当您将关系运算符应用于它们时,Date
个对象会强制转换为数字。因此,您可以可靠地使用dt1 > dt2
查看dt1
是否代表dt2
之后的日期/时间 - 但您无法使用dt1 == dt2
来检查如果dt1
和dt2
(两个单独的Date
个对象)具有相同的日期/时间,因为==
会检查它们是否是相同的对象。这让我们感到有点兴奋:
var dt1 = new Date(2016, 5, 23);
var dt2 = new Date(2016, 5, 23);
console.log(dt1 < dt2); // false
console.log(dt1 > dt2); // false
console.log(dt1 == dt2); // false!
所有血腥细节都可以在规范中找到:
答案 1 :(得分:6)
行为完全按照ECMAScript standards中的定义。
a == b
为false
,因为它们不引用the Abstract Equality Comparison section中定义的同一对象:
在检查完所有其他类型之后,
- 的结果 醇>
如果Type(x)与Type(y)相同,那么
一个。返回执行Strict Equality Comparison x === y。
The Strict Equality Comparison algorithm本身指定:
- 如果x和y是相同的Object值,则返回true。
- 返回false。
醇>
a < b
为false
因为the abstract relational comparison algorithm首先通过ToPrimitive abstract operation将操作数转换为非对象类型(在对象的情况下会生成一个字符串)代表"[object Object]"
)。
由于两个操作数都将转换为相同的字符串值,因此它们将彼此相等。
a <= b
为true
,因为b < a
为false
,根据the Less-than-or-equal Operator ( <= )的旧定义。
- 令r为执行抽象关系比较rval&lt;左边的Lval等于false。 (见11.8.5)。
- 如果r为true或未定义,则返回false。否则,返回true。
醇>
同样,抽象关系比较操作会将操作数转换为彼此相等的字符串表示"[object Object]"
,以便b < a
比较将评估为false
: