Below are some examples showcasing the different behaviors of prototypal inheritance based on how the objects are defined and created. I distinguish between the "prototype property" of an object, e.g. someObject.prototype
and the "prototype reference" (which I think should refer to the object from which someObject
inherits?).
Example 1
This seems to be the way to preserve the parent object's prototype property. Isn't this the recommended way of inheriting?
// create object whose prototype reference is Object; add stuff.
var Parent = Object.create(Object);
Parent.a = "1";
Parent.f = function() { return true; };
// add stuff to prototype property
Parent.prototype.b = 1;
Parent.prototype.g = function() { return false; };
// create an object whose prototype reference is Parent (??)
var Child = Object.create(Parent);
console.log(Parent.__proto__) // [Function: Object]
console.log(Parent.prototype) // { b: 1, g: [Function] }
console.log(Child.__proto__) // { a: '1', f: [Function] }
console.log(Child.prototype) // { b: 1, g: [Function] }
I would have expected
Child.__proto__
to be something namingParent
in the same wayParent.__proto__
namesObject
.We see that
Child
's prototype reference points to the properties ofParent
rather than the properties ofParent.prototype
. This is counterintuitive, to me at least, as I would have expected to seeParent.prototype
's propertiesb
andg
instead.
Example 2
Mixed results.
// use a constructor instead.
var Parent = function () {
this.a = "1";
this.f = function() { return true; };
}
// again, add stuff to prototype property.
Parent.prototype.b = 1;
Parent.prototype.g = function() { return false; };
// create an object whose prototype reference is Parent (??)
var Child = new Parent();
// create differently
var Sibling = Object.create(Parent);
console.log(Parent.__proto__) // [Function: Empty]
console.log(Parent.prototype) // { b: 1, g: [Function] }
console.log(Child.__proto__) // { b: 1, g: [Function] }
console.log(Child.prototype) // undefined
console.log(Sibling.__proto__) // [Function]
console.log(Sibling.prototype) // { b: 1, g: [Function] }
Here,
Child
's prototype referencesParents.prototype
's properties. This is what I expected above?On the other hand,
Sibling
's prototype reference is now a function, which is the prototype reference ofParent
.
Example 3
This seems to be the way to preserve the parent object's prototype reference, but you lose its prototype property.
// create object constructor; add stuff.
var Parent = function () {
this.a = "1";
this.f = function() { return true; };
}
// add stuff to prototype property.
Parent.prototype.b = 1;
Parent.prototype.g = function() { return false; };
// create an object whose prototype reference is Parent (??)
var Child = function() {
this.c = "2";
};
// supposed Ad-hoc prototype inheritance
Child.prototype = Object.create(Parent.prototype)
console.log(Parent.__proto__) // [Function: Empty]
console.log(Parent.prototype) // { b: 1, g: [Function] }
console.log(Child.__proto__) // [Function: Empty]
console.log(Child.prototype) // {}
Is the method shown in Example 1 preferred since you have access to both the parent's prototype property, its own properties as well as Object
's properties/methods? I've read in other posts that some of these ways of inheriting should be equal...which is not true. Also, I've read other posts, e.g. here, that Example 3 is the way to go. Or perhaps I am just not sure what __proto__
stands for...
Thanks for any clarification you might have for the differences between these mix and match situations!