I'm trying to create a prototype of a prototype in Javascript. Instead of the following functionality, utilizing normal prototypes, built from scratch, I'd like my prototypes to inherit certain methods without me adding them to each one.
So instead of this code, where I've added a method logDependencies()
within the prototype to check if there are any instances of Dependency
within the Car
instance:
function Dependency(data) {
this.data = data;
}
function Car(color) {
this.color = new Dependency(color);
this.logDependencies = function () {
for (var key in this)
if (this.hasOwnProperty(key))
if (this[key] instanceof Dependency)
console.log("Dependency: " + key);
};
}
var lamborghini = new Car("red");
lamborghini.logDependencies();
I'd like to instead have all of my prototypes inherit the function logDependencies()
, without me manually adding it.
How can I do this?
Update:
For those of you confused by my wording:
I'm trying to make a prototyping function that allows me to create prototypes who inherit certain properties and methods, passing them down the inheritance chain.
A related article by Douglas Crockford (emphasis my own):
My journey was circuitous because JavaScript itself is conflicted about its prototypal nature. In a prototypal system, objects inherit from objects. JavaScript, however, lacks an operator that performs that operation. Instead it has a new operator, such that
new f()
produces a new object that inherits fromf.prototype
.This indirection was intended to make the language seem more familiar to classically trained programmers, but failed to do that, as we can see from the very low opinion Java programmers have of JavaScript. JavaScript's constructor pattern did not appeal to the classical crowd. It also obscured JavaScript's true prototypal nature. As a result, there are very few programmers who know how to use the language effectively.
Fortunately, it is easy to create an operator that implements true prototypal inheritance. It is a standard feature in my toolkit, and I highly recommend it for yours.
function object(o) { function F() {} F.prototype = o; return new F(); }
The object function untangles JavaScript's constructor pattern, achieving true prototypal inheritance. It takes an old object as a parameter and returns an empty new object that inherits from the old one. If we attempt to obtain a member from the new object, and it lacks that key, then the old object will supply the member. Objects inherit from objects. What could be more object oriented than that?
So instead of creating classes, you make prototype objects, and then use the object function to make new instances. Objects are mutable in JavaScript, so we can augment the new instances, giving them new fields and methods. These can then act as prototypes for even newer objects. We don't need classes to make lots of similar objects.
For convenience, we can create functions which will call the object function for us, and provide other customizations such as augmenting the new objects with privileged functions. I sometimes call these maker functions. If we have a maker function that calls another maker function instead of calling the object function, then we have a parasitic inheritance pattern.
I have found that by using these tools, coupled with JavaScript's lambdas and object quasi-literals, I can write well-structured programs that are large, complex, and efficient. The classical object model is by far the most popular today, but I think that the prototypal object model is more capable and offers more expressive power.