There seems to be a mismatch between the common understanding of ==
and what it actually does. To give some background for the i开发者_开发百科ssue:
typeof new Number(1); // returns object
typeof new String(1); // returns object
typeof 1; // returns number
Seemingly, both Number
and String
are of object
type. No surprise there. However things get interesting for ==
which should return true
when operands are equal regardless of their type.
According to a somewhat authorative description:
Operators attempt to convert the object to a primitive value, a String or Number value, using the valueOf and toString methods of the objects. If this attempt to convert the object fails, a runtime error is generated.
In short, ==
should compare objects by their primitive value. Surprisingly:
var numa = new Number(1);
var numb = new Number(1);
var stri = new String(1);
numa.toString() == stri.toString(); // returns true, as expected
numa.valueOf() == stri.valueOf(); // returns true, as expected
numa == stri; // returns false (?!)
numa == numb; // returns false (?!!!)
numa == numa; // returns true, as expected
var numx = 1;
numa == numx; // returns true (?)
numb == numx; // returns true (?)
stri == numx; // returns true (?)
It appears when both operands are objects, the ==
operator uses neither toString()
nor valueOf()
but something else.
What is the standard definition of object equality for ==
?
I believe what you're seeing there, and what's left out of the "somewhat authoritative description", is that ==
attempts to convert an object to a primitive if, and only if, its comparand is a primitive. If both operands are objects, they're compared as objects, and the equality test is true only if they are the same object (i.e. same instance -- different objects with the same attributes are different, as you see in your numa == numb
case).
In short, when operands are objects then ==
compares references.
From official specification, page 80:
11.9.3 The Abstract Equality Comparison Algorithm
If Type(x) is the same as Type(y), then
a - e omitted, because not applying to objects
f. Return true if x and y refer to the same object. Otherwise, return false.
精彩评论