In this example of prototypal inheritance, we are creating a Bug prototype. It serves as a base to provide properties and methods that all bugs share. Then we will instantiate new instances of the Bug prototype for specific implementations.
var clone = function(o) {
function F(){}
F.prototype = o;
return new F;
};
// Our insect prototype
var Bug = {
species: "Prototype Bug",
attributes: [
'Three Body Segments',
'Six Legs',
'Exo-Sekelton'
],
getSpecies: function() {
return this.species;
}
};
var beetle = clone(Bug);
beetle.species = 'Beetle';
beetle.attributes.push('Eats Dung');
// we now have a child of the prototype with additional attributes.
console.log(beetle);
// The prototype
var ladyBug = clone(Bug);
ladyBug.species = 'Japanese Bug';
console.log(ladyBug);
The problem here is that the ladyBug object gets the attribute ‘Eats Dung’, because beetle actually modified a reference to the attributes in the prototype, not its own copy. This will trip up programmers that are used to a classical inheritance model.
The solution is to create factory functions to provide these properties and methods.
var Bug = {
getSpecies: function() {
return this.species;
}
};
Bug.species = 'default species';
Bug.addBugAttributes = function() {
var attr = ['three body segments', 'six legs', 'compound eyes'];
return attr;
};
Bug.attributes = Bug.addBugAttributes();
var beetle = clone(Bug);
beetle.species = 'Beetle';
beetle.attributes = Bug.addBugAttributes();
beetle.attributes.push('Eats Dung');
var ladyBug = clone(Bug);
ladyBug.species = 'Japanese Beetle';
ladyBug.attributes = Bug.addBugAttributes();
ladyBug.attributes.push('Eats Aphids');
console.log(ladyBug);
console.log(beetle);