Reputation: 835
When I type Object.prototype
into the Chrome console it displays Object{}
If I assign it to a variable var proto = Object.prototype
it displays Object{}
But if I check for it's prototype
var proto = Object.prototype
proto.prototype;
If proto
is an Object{}
and proto.prototype
is undefined does that means thatObject()
is an Object()
that doesn't inherit from anything?
Also, would this be the same as Object.prototype.prototype
?
Upvotes: 4
Views: 918
Reputation: 2456
A lot can be said about prototypes, but the brief explanations below could 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 its prototype
, just like how you were able to get the prototype
of Object
itself. This is because it is a function. typeof Object
returns "function"
. On the other hand, typeof Object.prototype
returns "object"
, so you were unable to get the prototype of 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 a Constructor
(which is a function) using the prototype
property.
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 (which includes functions).
Note that Object.__proto__
is equivalent to Object.constructor.prototype
and Object.getPrototype(Object)
.
There is no prototype
property of Object.prototype
because it is not a function. But because it is an object, we can do Object.prototype.__proto__
which returns null
. Getting null
means we are at the end of the prototype chain.
Even functions have __proto__
:
function Hello() {}
Hello.__proto__ // function Empty() {}
__proto__
is the internal prototype that is used by JS engines for inheritance/delegate chaining.
function Hello() {}
var hello = new Hello();
hello.__proto__ === Hello.prototype // true
Upvotes: 1
Reputation: 29999
Object.prototype
is the furthest you can go up the prototype chain.
It Object.prototype
has no prototype property, so what you see is undefined
. In actuality, it's prototype is null
. Which you can confirm with either the Object.getPrototypeOf
method or the __proto__
property.
Object.getPrototypeOf(Object.prototype); // null
Object.prototype.__proto__; // null
The prototype
property isn't a reliable way to traverse the prototype chain, as in many cases, it won't exist.
function MyObj() {}
MyObj.prototype.a = 3;
(new MyObj).prototype; // undefined
Object.create({ a: 3 }).prototype; // undefined
The __proto__
property is not a standard and may be removed from a future edition of ES. But in compatible browsers, it will work in the expected way.
Object.create({ a: 3 }).__proto__; // Object {a: 3}
Upvotes: 4
Reputation: 66364
If an Object has a prototype, the prototype is also an Object. These Objects all chain together until you reach null, 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
You should also note, however, that you can't keep accessing the obj.prototype
property, as this is only applicable to Constructors, consider
function Foo() {
}
Foo.prototype; // Foo {}
// vs
(new Foo).prototype; // undefined
The correct way to find the prototype of an Object is by using Object.getPrototypeOf(obj)
,
Object.getPrototypeOf(new Foo) === Foo.prototype; // true
It may also be of note 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 a shim for such browsers if you need to access the prototype chain.
Finally, using new
with a Constructor isn't the only way to create this chain, you can set them up using Object.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
Upvotes: 5