Object.prototype - object and prototype somehow not?
When I type Object.prototype
in the Chrome console it displaysObject{}
If I assign it to a variable var proto = Object.prototype
it displaysObject{}
But if I check its prototype
var proto = Object.prototype
proto.prototype;
If proto
is Object{}
and proto.prototype
is undefined, does that mean which Object()
is Object()
, which inherits nothing?
Also, will it be the same as Object.prototype.prototype
?
If an object has a prototype, the prototype is also an object. These objects all chain together until you reach zero, which is the end of the prototype chain.
// Object is a constructor
Object.prototype; // Object {}, will be the prototype of `new Object`s
// Object.prototype is an Object
Object.getPrototypeOf(Object.prototype); // null, we are at the end of the chain
It should also be noted that you cannot continue to access the property obj.prototype
as this only applies to constructors, consider
function Foo() {
}
Foo.prototype; // Foo {}
// vs
(new Foo).prototype; // undefined
The correct way to find the prototype of an object is with Object.getPrototypeOf(obj)
,
Object.getPrototypeOf(new Foo) === Foo.prototype; // true
It may also be noted that legacy browsers may not support Object.getPrototypeOf
, in which case many offer the property obj.__proto__
. However, try to avoid using __proto__
outside of the shim for such browsers if you need to access the prototype chain.
Finally, using new
with a constructor is not the only way to create this chain, you can customize them withObject.create
var a = Object.create(null),
b = Object.create(a), // b will inherit from a
c = Object.create(b); // c will inherit from b, hence also a
a.foo = 'foo';
b.bar = 'bar';
a instanceof Object; // false
a.bar; // undefined
c.foo + c.bar === 'foobar'; // true
Also consider
c.prototype; // undefined
// vs
Object.getPrototypeOf(c) === b; // true
Object.prototype
is the farthest you can climb the prototype chain.
It Object.prototype
has no prototype property, so you see undefined
. In fact, it is a prototype null
. Which you can confirm with either a method Object.getPrototypeOf
or a property __proto__
.
Object.getPrototypeOf(Object.prototype); // null
Object.prototype.__proto__; // null
A property is prototype
not a reliable way to traverse a prototype chain, as in many cases it will not.
function MyObj() {}
MyObj.prototype.a = 3;
(new MyObj).prototype; // undefined
Object.create({ a: 3 }).prototype; // undefined
This property is not standard and may be removed from a future ES release. But in compatible browsers it will work as expected. __proto__
Object.create({ a: 3 }).__proto__; // Object {a: 3}
There is a lot to be said for prototypes, but the brief explanations below may help clarify the subject to make it easier to understand:
A) prototype
is a property of functions .
Object.constructor
returns function Function() { [native code] }
, so we can get it prototype
just like you could get it prototype
from Object
. This is because it is a function. typeof Object
returns "function"
. On the other hand, it typeof Object.prototype
returns "object"
, so you couldn't get a prototype Object.prototype
.
// get prototype property of a function
var hello = function () {};
hello.prototype // hello {}
// get prototype property of an object
typeof hello.prototype // "object"
hello.prototype.prototype // undefined
hello = {};
hello.prototype // undefined
We can add properties and methods to Constructor
(which is a function) using property prototype
.
function Hello() {}
Hello.prototype.print = function () { console.log('hello'); };
// not using a constructor
var hello = Hello(); // undefined
hello.print(); // ERROR
// using a constructor
hello = new Hello(); // Hello {print: function}
hello.print(); // "hello"
B) __proto__
is a property of all objects (including functions) .
Note that it is Object.__proto__
equivalent to Object.constructor.prototype
and Object.getPrototype(Object)
.
There is no prototype
property Object.prototype
because it is not a function. But since it is an object, we can do Object.prototype.__proto__
that returns null
. Receiving null
means that we are at the end of the prototype chain.
Even functions have __proto__
:
function Hello() {}
Hello.__proto__ // function Empty() {}
__proto__
is an internal prototype that is used by JS engines for inheritance / delegation chain.
function Hello() {}
var hello = new Hello();
hello.__proto__ === Hello.prototype // true