Primitives and objects
Final JavaScript by David Flanagan makes a distinction between objects and primitives.
It defines primitives as Number, String, Boolean, Null and Undefined, just like the standard one.
However, it would be more accurate to define a primitive as a subset of an object, i.e. call them primitive objects.
Because they have their own methods and are complex entities.
Actual question
Will a primitive object be more precise than Object in defining String, Boolean and Number?
Objects and primitives are different:
typeof 42 === "number"
typeof new Number(42) === "object"
new Number(42) !== 42
However, primitives are automatically wrapped in temporary objects when needed, which can be automatically converted back to primitives :
(42).toString() === "42"
new Number(42) == 42
new Number(42) + 1 === 43
Especially in the context of the Java and C # programming languages, this behavior is called autoboxing . Because wrapper objects have some confusing characteristics, for example:
Boolean(new Boolean(false)) === true
it is good practice to avoid intentionally storing them in variables and instead use primitives whenever possible.
source to share
It's not about semantics, take a look:
var threePrimitive = 3;
var threeObject = new Number(3);
threePrimitive.toFixed(2); // 3.00
threeObject.toFixed(2); // 3.00
threePrimitive.foo = true
threeObject.foo = true;
threePrimitive.foo; // undefined
threeObject.foo; // true
Primitives are wrapped in objects when you try to call a method on them, but after initial use, the object is discarded.
As for how the spec says it, I'm not 100% sure, but here's what I think (based on advice left by Bergi in one of his answers 11.2.1 states that accessor properties should be evaluated like this:
- Let baseReference be the result of evaluating MemberExpression.
- Let baseValue be
GetValue
(baseReference).(...)
Then in 8.7.1 we see the following:
The [[Get]] internal method is used by GetValue when V is a property with a primitive base value. It is called using base as its value
this
and the P property as an argument. the following steps are performed:
- Let O be a TOObject (base).
- Let desc be the result of calling the [[GetProperty]] internal method O named property P.
- If desc is undefined, return undefined.
- If IsDataDescriptor (desc) is true, return descending. [[Value]].
- Otherwise IsAccessorDescriptor (desc) must be true, so
- let getter be desc. [[Get]]. If getter is undefined, return undefined.
- Returns a result that calls the internal get [[Call]] method providing the base as this value and no arguments.
NOTE. the object that can be created in step 1 is not available outside the above method. The implementation may decide to avoid actually creating the object. The only situation where such real property access that this internal method uses might have a visible effect when it calls the accessor function.
source to share
Will a primitive object be more precise than Object in defining String, Boolean and Number?
Note that I am not saying that the numbers here are not objects, I am indicating that it is displayed ambiguously. This is what confuses JavaScript newbies.
The distinction is mostly academic, but there is one case where it seems ambiguous: literals are primitive objects, except when the literal is a number. You cannot apply the method directly to the literal integer * character:
1.toString();
SyntaxError: identifier starts immediately after numeric literal
... but you can apply Numbers methods:
Number(1).toString();
'1'
... and the name that contains the number is Number:
x = 4; x.toString(); '4'
I think this is actually a parsing problem, but I don't know why the parser cannot tell what 1
is a number as easily as it can tell "abc" is a string. I believe this is due to the semantic ambiguity of the symbol .
. (Is this a decimal point or a method statement?)
* JavaScript doesn't actually have integers. I just mean a symbol that is entirely composed of [0-9]+
.
source to share