Last week we talked about JavaScript inheritance and if you recall we had talked about modular design patterns in JavaScript just a month ago. I would also like to talk about how to connect both modules and class inheritance. We've already discussed that modules are classes. So if we can link classes by inheritance relationship, the logical half of our brain suggests that we should be able to link modules as well. The logic prevails - we can.
AMD and inheritance
I'll be using the classes we defined in the inheritance article, Mammal and Dog, and create modules from them. Let's start with our super class:
(function () { 'use strict'; define(function() { function Mammal() { this.age = 0; console.info("Mammal was born"); } Mammal.prototype.grow = function() { this.age += 1; console.log("Mammal grows"); }; return Mammal; }); }());Let's use it in our entry point JavaScript file. Just to remind you this file is declared in data-main attribute.
(function () { 'use strict'; require(["Mammal"], function(Mammal) { var m = new Mammal(); m.grow(); } ); })();Now it's time to create our Dog module. Since it needs Mammal for the inheritance, we'll list it in our dependency list. The implementation remains the same.
(function () { 'use strict'; define(["Mammal"], function(Mammal) { function Dog(name) { this.name = name; Mammal.call(this); } Dog.prototype.grow=function(){ this._super.grow.call(this); this.age =+ 1; console.log('Dog grows'); } Dog.prototype = Object.create(Mammal.prototype); Dog.prototype.constructor = Dog; Dog.prototype._super = Mammal.prototype; return Dog; }); })();And of course update our main file to see if it works:
(function () { 'use strict'; require(["Mammal", "Dog"], function(Mammal, Dog) { var m = new Mammal(), d = new Dog('Rocky'); m.grow(); d.grow(); } ); })();
CommonJS and inheritance
As you recall modules should be defined using the CommonJS syntax if you want to use them in Node.js.
(function () { 'use strict'; function Mammal() { this.age = 0; console.info("Mammal was born"); } Mammal.prototype.grow = function() { this.age += 1; console.log("Mammal grows"); }; module.exports = Mammal; }());As you can see we removed define method call and replaced return with module.exports.
(function () { 'use strict'; var Mammal = require('Mammal'); function Dog(name) { this.name = name; Mammal.call(this); } Dog.prototype.grow=function(){ this._super.grow.call(this); this.age =+ 1; console.log('Dog grows'); } Dog.prototype = Object.create(Mammal.prototype); Dog.prototype.constructor = Dog; Dog.prototype._super = Mammal.prototype; module.exports = Dog; })();Here instead of listing the dependencies, we just require the Mammal class in our Dog definition.