var someObj = function() { }
var p = new someObj();
alert(someObj.prototype); // This works
alert(p.prototype); // UNDEFINED, but why?
someObj.prototype.model= "Nissan";
alert(p.model); // This works! I understand the dynamic nature of prototypes, but doesn't that mean that p.prototype === someObj.prototype?
Why is this so? Since "p" is an instance of "someObj", why is the prototype undefined? I mean, when I add a property to "someObj" prototype, it is accessible to "p", so why is the prototype not accessible?
The important thing here is that the prototype
property of function objects is not the prototype of an object. It's the object that will be assigned as the prototype of an object you create via new someObj
. Prior to ES5, you can't directly access the prototype of an object; as of ES5, you can, via Object.getPrototypeOf
.
Re
alert(p.prototype); // UNDEFINED, but why?
The reason is that the p
object doesn't have a property called "prototype". It has an underlying prototype, but that's not how you access it.
All function objects have a property called prototype
so that if they're used as constructor functions, we can define what the properties of the underlying prototype of the objects created by those constructors will be. This may help:
function Foo() {
}
Foo.prototype.answer = 42;
console.log(Foo.prototype.answer); // "42"
var f = new Foo();
console.log(f.answer); // "42"
That last line works like this:
f
object.f
have its own property called "answer"?f
have a prototype?You've mentioned Object.create
in the title of your question. It's important to understand that Object.create
is quite separate from constructor functions. It was added to the language so that if you preferred not to use constructor functions, you didn't have to, but could still set the prototype of an object — directly, when you create that object.
That's because prototype
is a property of the constructor function, not a property of itself. However, the prototype
object has a reference to the constructor, so you can access an object's prototype
via its constructor
property:
function Foo() {}
Foo.prototype.foo = "bar";
var c = new Foo;
console.log( c.constructor === Foo ); // true
console.log( c.constructor.prototype ); // { foo: 'bar' }
However, this will not work if you overwrite the initial prototype
property of the constructor function:
function Foo() {}
// I overwrite the prototype property, so I lose the initial reference
// to the constructor.
Foo.prototype = {
foo: "bar"
};
var c = new Foo;
console.log( c.constructor === Foo ); // false
console.log( c.constructor === Object ); // true
console.log( c.constructor.prototype ); // {}
That's why you're better off using the new Object.getPrototypeOf
method introduced in ES5.
function Foo() {}
Foo.prototype = {
foo: "bar"
};
var c = new Foo;
console.log( c.constructor === Foo ); // false
console.log( c.constructor === Object ); // true
console.log( c.constructor.prototype ); // {}
console.log( Object.getPrototypeOf(c) ); // { foo: 'bar' }
Another solution would have been to make sure you restore the constructor
reference on the prototype:
function Foo() {}
// Overwriting the initial prototype
Foo.prototype = {
constructor: Foo, // restore the constructor reference
foo: "bar"
};
p.prototype doesn't work because in this case p = someObj.prototype.
Basically when you use the new operator what happen is that the constructor someObj is used to initialize a new object. Which means it returns an object which have the properties and methods of the prototype of the constructor.
Thus p = someObj.prototype and p.prototype is undefined as p is not a constructor.
This article might help explains this more
http://www.htmlgoodies.com/html5/tutorials/javascript-prototypical-inheritance-explained.html#fbid=A2ikc3JLxeD
p
is an instance of someObj
. The prototype belongs to the constructor. You can retrieve p
's constructor prototype using p.constructor.prototype
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With