views:

72

answers:

1

Maybe this question is easy,but I can't understand now.

String.prototype.self=function()
{
    return this;
}
var s="s";

alert("s".self()=="s".self()) //false;
alert(s.self()==s.self()) //false;

If you know the reason, please tell me why the result is "false".

+8  A: 

That's because when a property is accessed from a primitive value, such as "s", the property accesors coerce it internally ToObject, and the comparison fails because it checks two different object references.

For example:

String.prototype.test = function() {
  return typeof this;
}

"s".test(); // "object"

It's like comparing:

new String("s") == new String("s"); // false
CMS
Why does the second example fail?
Graphain
@Graphain in the expression `s.self() == s.self()`, the value contained in the `s` variable is coerced two times `ToObject`, since `s` holds a primitive, when the dot (`.`) property accessor is used, is coerced to object for being able to access the `String.prototype` members. The comparison would be roughly equivalent to `var s = 's'; new String(s) == new String(s);` which also yields `false`.
CMS
@Graphain in layman terms, although both string objects contain the same data, they are different objects, and thus == false.
Stephen
Forgot to mention that in the ECMAScript 5th Ed. Standard, the OP code will work as expected under [strict mode](http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/). Primitives are no longer implicitly converted to object in this case.
CMS