Why, in JavaScript, does '3 instanceof Number' == false, but '3..method()' will call Number.prototype.method?
Asked Answered
D

1

7

Given that a literal number not strictly an instance of Number, why can I call prototype methods of Number (or String, or Boolean) objects on the corresponding literal objects? Is this standard behavior across browsers?

What exactly is happening when this occurs? I suspect it's coercing the literal into the corresponding type before calling the method, because when I inspect typeof this in the method, it's returning 'object' rather than 'number'.

Depression answered 8/11, 2016 at 15:55 Comment(5)
3 is not an instance of Number, it's a type number. For an instance of something, it would need to be of type object. So typeof 3 = number, typeof new Number(3) = object, You can coerce a built in type 'number, string' etc, by Object(3) instanceof Number, this would return true, you could also do for other built's like String etc. or either var x = 3; x = Object(x); x is now instanceof Number.Ysabel
So if you wanted a simple isNumber check -> function isNumber(n) { return typeof n === 'number' || n instanceof Number; }Ysabel
No, I already define those checks. In fact, that implementation isn't safe across browser windows for instances of Number that come from another window. It's better to use function isNumber(n) { return Object.prototype.toString.call(n) === '[object Number]'; }, which works for number primitives, number intances, and number instances from other windows. It's also the default implementation for shims like Array.isArray.Depression
isn't safe across browser windows, isn't that the case of instanceof that your talking about here?.. You mentioned nothing about IPC between windows / iframes. So I'm a little confused why your even talking about instanceof in this respect.Ysabel
See Also: Why is 4 not an instance of Number?Intwine
C
6

The literal is not coerced into an instance.

What happens internally, is that an instance is created, the value is copied to the instance and the method is carried out using the instance. Then the instance is destroyed. The literal is not actually being used to carry out the method. This "wrapper" object concept is also used with string primitives when they are used like String objects. This behavior is standard.

3 is a number literal. Not an instance of the Number type. JavaScript has a primitive number type and a native Number object.

From MDN: In contexts where a method is to be invoked on a primitive string or a property lookup occurs, JavaScript will automatically wrap the string primitive and call the method or perform the property lookup.

Constructivism answered 8/11, 2016 at 15:56 Comment(12)
That's not what I'm asking at all. That's the given. The question is why can I call methods of Number on a literal that is NOT a Number.Depression
@You keep editing your question and I keep updating my answer to keep up!Constructivism
No, I only edited the first line to clarify. The question has always stated that 3 is not an instance of Number, and asks why I can still call methods of Number on it. Furthermore, it's asking whether it's standard/reliable behavior. This answers has addressed neither. First, it restated the given, then it restated my suspiction that it's coercing it into an instance. It still hasn't addressed whether it's standard behavior.Depression
@Depression You can argue or look at my answer, which (in bold) answers your question.Constructivism
It doesn't answer it, even after your 4th edit, lol. See previous comment.Depression
The edits have been purely grammatical. That complex boxing is an awfully big assertion to make without any references in the spec. The way you differentiate between the types is misleading.Lockhart
"why can I call prototype methods of Number (or String, or Boolean) objects on the corresponding literal objects" and "What exactly is happening when this occurs?" The bold text answers both these questions.Constructivism
I trust that the boxing is occurring, so that answers half of it. But is it standard/reliable behavior. I'm more concerned with whether my definition of, for example, Number.prototype.equals, will consistently and reliably be invoked on numeric literals on older browsers, or if this is something special or new.Depression
Yes it is standard behavior.Constructivism
Thanks! I'll mark it as the answer once I verify where it is in the spec.Depression
Very relevant: jisaacks.com/javascript-boxing as well as javascriptweblog.wordpress.com/2010/09/27/…Depression
Found it in the spec! See "ToObject": ecma-international.org/ecma-262/5.1/#sec-9.9 Very clear.Depression

© 2022 - 2024 — McMap. All rights reserved.