Reputation: 5916
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
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
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