Possible Duplicate:
Why does (“foo” === new String(“foo”)) evaluate to false in JavaScript?
Over here I caught the advice that it’s best to use non type-coercive string comparison, but in Chrome, I discovered something kind of odd:
var t1 = String("Hello world!");
var t2 = new String("Hello world!");
var b1 = (t1==t2); // true
var b2 = (t1===t2); // false
Is this standard behavior? If so, what are the respective types of t1 and t2? Thanks.
String, called as a function, converts its argument to astring.String, called as a constructor, creates an object whose prototype is theStringfunction. (Check James’s Answer for the relevant ECMAScript specification section.)This is indeed confusing.
The two equality operators actually do very different things. From the ECMA-262, v 5.1 document,
===does:Whereas
==does:Note that in the spec, the
Typeof a primitive string object isString, whereas the type of any object (including theStringobject) isObject.With
===the relevant line is#1: theTypeof the objects are different, sofalseis returned.With
==the relevant line is#8:xis aString("Hello world!") andyis anObject(TheStringobject containing the string"Hello world!"). Thus the comparisonx == ToPrimitive(y)is made.ToPrimitiveends up calling thevalueOfmethod of the object, or if that method doesn’t exist, thetoStringmethod. In this case, aStringobject‘svalueOfmethod returns the primitivestringthe object contains. Thus the equality operation is done again, this time between two primitivestrings which contain the same text, which returnstruethanks to#1.d.JavaScript is a bit messy under the hood…
EDIT: Notice that if two objects are compared, no conversions apply, but rather, rule
#1.fapplies. Thus, thanks to the spec, I was able to correctly predict the output of the following code:EDIT: Just thought I’d add that these distinctions are even further blurred by more implicit type conversion. For example, the following works:
but that’s not because
"hi"is an object (like in Python):But rather, because the
.operator does a conversion from the primitivestringtype to the stringObjecttype (creating a new string object) whosetoStringmethod is then called.