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 namingParentin the same wayParent.__proto__namesObject.We see that
Child's prototype reference points to the properties ofParentrather than the properties ofParent.prototype. This is counterintuitive, to me at least, as I would have expected to seeParent.prototype's propertiesbandginstead.
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!