Every variable stems from Object, right?
Incorrect, and here's why:
1. In JavaScript (including TypeScript), we have both objects and primitives. this
can hold any value (in strict mode), even a primitive:
"use strict";
foo();
foo.call(42);
function foo() {
console.log(typeof this);
}
Try it in the TypeScript playground. In both examples, the output is:
Object
.
2. Some objects do not inherit from Object.prototype
:
var obj = Object.create(null);
console.log(typeof obj.toString); // undefined
console.log("toString" in obj); // false
If an object's prototype chain starts with an object that lacks a prototype (like obj
above), it won't have the characteristics of Object.prototype
.
In response to your comment below:
I was under the impression that even primitive types like number
derive from Object
. If not, how does number.ToString()
function?
Primitives are standalone entities and do not inherit from Object
. However, certain primitives appear to, including number
, string
, boolean
, and symbol
, which have corresponding objects (Number
, String
, Boolean
, and Symbol
) derived from Object
. Not all primitives follow this pattern: undefined
and null
cause a TypeError
when treated as objects. (Interestingly, null
is a primitive despite its "object"
typeof.)
For the four primitives mentioned, when used as objects like this:
var a = 42;
console.log(a.toString());
An appropriate object type is momentarily created from the primitive through the abstract operation ToObject
as dictated by the spec, and the object's method is invoked; upon completion (no method returns the object reference), the temporary object is cleared for garbage collection. (JavaScript engines optimize common operations such as toString
or valueOf
.)
A simple test reveals the ephemeral nature of the object:
var a = 42;
console.log(a); // 42
console.log(typeof a); // "number"
a.foo = "bar"; // temp object created and discarded
console.log(a.foo); // undefined, no reassignment to `a`
var b = new Number(42);
console.log(b); // (Refer to notes)
console.log(typeof b); // "object"
b.foo = "bar"; // since `b` references an object, property persists...
console.log(b.foo); // ... "bar"
(Regarding the note: In Stack Snippets console, you'll see {}
; Chrome's native console varies—closed shows 42
; open displays ▶ Number {[[PrimitiveValue]]: 42}
, expandable with ▶.)
Does number
implement a unique toString
method unrelated to Object
?
The answer is yes, impacting our understanding of primitives and their peculiar association with Object
.
Recapping:
this
could store a primitive; while some primitives allow object-like behavior, others prohibit it.
this
might feature an object pointer devoid of Object
heritage (implying absence of Object.prototype
within its prototype lineage).
IntelliSense faces hurdles in deciphering JavaScript. :-)