cemerick
cemerick

Reputation: 5916

typeof returns "object" for `this`, "number" elsewhere

typeof evaluates to different strings when applied to the same value in different contexts. For example, this is expected:

> typeof 5
'number'

...and yet, the typeof 5 when accessed via this is not the same:

> Number.prototype.foo = function () { return typeof this; };
[Function]
> (5).foo()
'object'

Just another (in)sanity check, to really, seriously verify that this is a number:

> Number.prototype.foo = function () { return [this + 1, typeof this]; };
[Function]
> (5).foo()
[ 6, 'object' ]

I've read through the MDN docs and the ECMAScript spec for typeof, and can't imagine how this is to be expected, nevermind correct. Does anyone have an explanation?

Upvotes: 3

Views: 114

Answers (2)

Tibos
Tibos

Reputation: 27833

The trick here is that your test case changes 5 to an object.

Whenever you access a property on a primitive value(boolean, number or string), the primitive value is converted to an object of the appropriate type (Boolean, Number or String) and the property access is resolved on that object.

I have written more on this topic here and here

The correct method to show the type is:

Number.prototype.foo = function () { return typeof this.valueOf(); };
(5).foo() // "number"

Your sanity check converts the Object wrapper back to the primitive value when you do this+1:

(new Number(5)) + 1 // 6

Upvotes: 5

jeremija
jeremija

Reputation: 2528

My guess is that (5) casts the primitive type number to a Number object.

Try adding a function like this:

Number.prototype.foo2 = function() { console.log(this); }

and you'll get a result like this in Chrome after you call (5).foo2():

Number {foo: function, foo2: function}
    __proto__: Number
    [[PrimitiveValue]]: 5

Upvotes: 0

Related Questions