[...] It looks like a primitive number has methods
The primitive does not have its own properties. He receives coercion to the object in order to be able to access its "properties". A coherent object is not available outside the called method * (in strict mode, not even inside the method) *. Thus, the reference variable is always primitive.
Consider this simple example:
Number.prototype.myTypeInAMethod = function () { console.log (typeof this.valueOf ()) //"number" => The primitive is wrapped in an object. return typeof this; } var num = 123; typeof num; //number num.myTypeInAMethod () //object
Note: in strict mode ES5 this will be primitive and the type will have a number
Since the num variable is primitive, you can choose not to assign values ββto it.
num.foo = "bar"; num.foo //undefined
If you instead create a number (or string) through your object constructor, its type is indeed an object. A quick check by adding a property indicates that it can be assigned.
var objNum = new Number(123); typeof objNum ; //"object" objNum.foo = "bar"; objNum.foo //"bar"
So what is this magic? How does JavaScript handle objects compared to primitive types?
This process is described in ES5 Β§8.7.1 GetValue
For an object:
- If
Type(V) not a link, return V. - Let base be the result of calling
GetBase(V) . - If
IsUnresolvableReference(V) , throw a ReferenceError exception. - If
IsPropertyReference(V) , then- If
HasPrimitiveBase(V) false , then let get be the internal method of the [[Get]] base, otherwise let there be a special internal method [[Get]] defined below. - Returns the result of calling the internal get method using the base as the value of this and passing
GetReferencedName(V) for the argument.
- Otherwise, the base should be an environment record.
- Returns the result of calling
GetBindingValue (see 10.2.1 ) the specific method for passing the GetReferencedName(V) and IsStrictReference(V) as arguments.
For primitive:
The [[Get]] internal method is used by GetValue when V is a property reference [1] using the base value . It is called using the base as its value and with the P property as an argument. The following steps have been taken:
- Let O be
ToObject(base) . - Let desc be the result of calling the [[GetProperty]] O internal method with property name P.
- If desc is undefined , return undefined .
- If
IsDataDescriptor(desc) true , return desc. [[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 get [[Call]] getter internal method, providing the base as the value of this and not providing any arguments.
<sub> NOTE The object that can be created in step 1 is not accessible outside the above method. An implementation may decide to avoid actually creating the object. The only situation where such actual access to a resource that uses this internal method can have a visible effect when it calls the access function. Sub>
[1] IsPropertyReference(V) . Returns true if either the base value is an object or HasPrimitiveBase(V) is true ; otherwise returns false .
Moritz Roessler Feb 21 '14 at 11:32 2014-02-21 11:32
source share