In JavaScript not every data is an object. There exist a few primitive types, like strings, numbers and Boolean which are not objects. For each of these types there exists a constructor which outputs an object with similar behaviour: Number
, String
and Boolean
. To confuse matters, one actually can call methods on primitive types - they will be converted to the corresponding objects during this operation, and then converted back. For instance one can do
var a = 4.1324;
a.toFixed(1) // Outputs 4.1
Yet, if you try to compare primitive types and objects with strict equality, the difference shows up
var a = new Number开发者_JS百科(4);
var b = 4;
a === b; // False!!!
typeof a; // 'object'
typeof b; // 'number'
Actually of one tries to compare objects, they turn out to be different anyway:
var a = new Number(4);
var b = new Number(4);
a === b; // False!!!
(From a conceptual point of view I sort of understand the distinction. Objects can have additional properties, hence they should not compare to equal unless they are actually the same. So if we want to have 4 === 4
we need to use a type which is not an object. But this dilemma is faced by any sufficiently dynamic programming language, yet JavaScript is the only one I know where there are two types - one objectful and one not - for numbers or strings.)
What is the advantage of keeping two separate representations for numbers, strings and Booleans? In what context could one need the distinction between primitive types and objects?
What is the advantage of keeping two separate representations for numbers, strings and Booleans?
Performance
In what context could one need the distinction between primitive types and objects?
Coercion comes to mind. 0 == false
while new Number(0) != false
So for instance:
var a = new Boolean(false);
if(a) {
// This code runs
}
but
var a = false;
if(a) {
// This code never runs
}
You can read more about coercion here: JavaScript Coercion Demystified
What is the advantage of keeping two separate representations?
As you point out, you can call methods on unboxed values too (a.toFixed(1)). But that does cause a conversion. In other words, an instantiation of a new boxed object (probably) every time you call such a method.
So there is a performance penalty right there. If you explicitly create a boxed Number and then call its methods, no further instances need to be created.
So I think the reason for having both is much historical. JavaScript started out as a simple interpreted language, meaning performance was bad, meaning any (simple) way they could increase performance was important, such as making numbers and strings primitive by default.
Java has boxed vs. unboxed values as well.
精彩评论