JavaScript string weirdness

Recently, I mentioned a peculiar difference between uneval and toSource. Specifically (using the SpiderMonkey JS console):

js> uneval("");
js> "".toSource();
(new String(""))

"" and new String("") are different types of objects. The first is the basic string type, and only really has a value. The second is a full Object, that happens to have a value. However, it turns out that if you treat a basic string type as an Object, say by putting ‘.’ after it in an expression, the SpiderMonkey runtime will implicitly promote the string to a String. Hence, "".toSource() promotes the string object, then calls toSource on the new String object.

Annoyingly, the String Object doesn’t hang around, it’ll get thrown away as soon as you’re done with it. This leads to the weird case that you can set attributes on a basic string type (because it’ll get promoted to an Object, and Objects have attributes) but they don’t stay set (because the Object you’ve set them on gets thrown away as soon as the set call finishes).

By the way, all of this applies very specifically to the current CVS trunk SpiderMonkey. I don’t know what most web browser engines do with strings, so don’t assume this applies in, say, Internet Explorer. But I’d be interested if someone wants to find out and tell me…