tags:

views:

55

answers:

3

If you look at the ECMAScript 3 specification you will see that primitive value types Null and Undefined don't have accompanying Null and Undefined Objects.

>> Null
ReferenceError: Null is not defined

The other primitive value types Number, String and Boolean types do have accompanying Number, String and Boolean objects which you can reference from global scope.

>>Number
function Number() { [native code] }
>>Boolean
function Boolean() { [native code] }

The purpose for these primitive value types is to provide methods such as toString and valueOf for their respective primitive value types:

>>var n = 1;
>>n.toString();
"1" 

is the same as

>>var n = 1;
>>Number.prototype.toString.call(n);
"1"

Booleans and strings also work that way:

>>var b = true;
>>b.toString(); 
"true"
>>Boolean.prototype.toString.call(b);
"true"

You can see that the primitive value objects are using the methods of their accompanying object when you try to mix types:

>>Boolean.prototype.toString.call(n); 
TypeError: Boolean.prototype.toString is not generic
>>Number.prototype.toString.call(b)
TypeError: Number.prototype.toString is not generic

Interestingly enough for boolean and string literal types, you can call these methods directly from the literal:

>>true.toString();
"true"
>>Boolean.prototype.toString.call(true)
"true"
>>"moo".toString();
"moo"
>>String.prototype.toString.call("moo")
"moo"

Primitive values null and undefined, since they don't have accompanying Null and Undefined objects cannot do these things:

>>Null
ReferenceError: Null is not defined
>>null.toString()
TypeError: Cannot call method 'toString' of null

Primitive value type number behaves like a mix of the two. You can call toString on a literal if you directly use the Number's prototype object's method:

>>Number.prototype.toString.call(1);
"1"

But you cannot access the method from the literal itself like you can with strings and booleans:

>>1.toString()
SyntaxError: Unexpected token ILLEGAL

Why is it that number literals behave differently from boolean and string even though there's a Number object?

+7  A: 

You can access it the same way, it's a different parsing issue here, to do it, use a slightly different syntax:

(1).toString()

Numbers can have decimals, so the syntax for ending in a decimal is a bit ambiguous when you go to parse the code, use parenthesis to be valid. It's a bit clearer when you see that this is also valid:

(1.).toString()

However with just 1.toString() it's trying to parse as a number with a decimal, and it fails.

Nick Craver
Didn't consider to try it with (). Wish I could mark two answers as answers. So basically the literal has the property, but you just have to deal with the extra decimal syntax. Thanks!
apphacker
1..toFixed(2), 1.0.toFixed(2) work without parens.
kennebec
@kennebec - Yes, they'll work as well, I was more conveying that `(anyType).toString()` would be a consistent format that would work, sorry if that wasn't entirely clear...didn't mean to imply there weren't alternatives for numbers specifically.
Nick Craver
+2  A: 

I think you'll find an answer to your question in this answer to another Stack Overflow question. To summarize Theo's answer:

[T]he parser expects a number followed by a dot to be a floating point literal. [...] [Y]ou only have to add another dot to make it work[.]

awayken
Wow! I figured it had something to do with the decimal, but I thought there would be more to it. Interesting, see I'm glad I asked.
apphacker
A: 

Null (capital N) is a variable name. Reserved words are case sensitive. null is the object null. typeof null === "object" //true

AutoSponge