35

I am in process of writing nodejs app. It is based on expressjs. I am confused on doing inheritance in nodejs modules. What i am trying to do is create a model base class, let's say my_model.js.

module.exports = function my_model(){
  my_model.fromID = function(){
    //do query here
  }
}

Now i want to use those methods in my_model in my other model class. let's say user_model.js How do i inherit my_model in user_model?

fardjad
  • 20,031
  • 6
  • 53
  • 68
Yalamber
  • 7,360
  • 15
  • 63
  • 89

3 Answers3

45

in base_model:

function BaseModel() { /* ... */ }

BaseModel.prototype.fromID = function () { /* ... */ };

module.exports = BaseModel;

in user_model:

var BaseModel = require('relative/or/absolute/path/to/base_model');

function UserModel() {
    UserModel.super_.apply(this, arguments);
}

UserModel.super_ = BaseModel;

UserModel.prototype = Object.create(BaseModel.prototype, {
    constructor: {
        value: UserModel,
        enumerable: false
    }
});

UserModel.prototype.yourFunction = function () { /* ... */ };

module.exports = UserModel;

Instead of using Object.create() directly, you can also use util.inherits, so your user_model becomes:

var BaseModel = require('relative/or/absolute/path/to/base_model'),
    util = require('util');

function UserModel() {
    BaseModel.apply(this, arguments);
}

util.inherits(UserModel, BaseModel);

UserModel.prototype.yourFunction = function () { /* ... */ };

module.exports = UserModel;
fardjad
  • 20,031
  • 6
  • 53
  • 68
  • Can we use utils.inherits in this? – Yalamber Apr 25 '13 at 11:41
  • @askkirati Yes, see the updated answer. `util.inherits` does something very similar to what I've done, it's just my preference to use `Object.create()` directly. – fardjad Apr 25 '13 at 11:51
  • Hello, how should i access fromID from where i have loaded the UserModel modeule? if i do `var user_model = require('./UserModel');` then doing `user_model.fromID();` gives undefined user_model to me – Yalamber Apr 25 '13 at 17:44
  • 3
    you should do `var userModel = new require('./UserModel');` – fardjad Apr 25 '13 at 19:12
  • I did this var userModel = new (require('./UserModel'))(params); I needed to pass paramater aswell. this is correct right. it worked – Yalamber Apr 26 '13 at 04:15
  • what is the point of this line? `UserModel.super_.apply(this, arguments);` – chovy Jan 08 '15 at 10:06
  • @chovy [Delegating](https://en.wikipedia.org/wiki/Delegation_pattern) the construction to the superclass – fardjad Jan 08 '15 at 12:05
  • 1
    public methods are not exposed. What's the point of inheritance if you have to manually define them each time? – Oliver Dixon Jun 29 '16 at 19:00
  • @OliverDixon all properties and methods are exposed here. What do you mean really? – Fahmi Mar 29 '17 at 16:11
27

With ES6 the usage of util.inherits() is discouraged in favor of ES6 class and extends

const EventEmitter = require('events');

class MyStream extends EventEmitter {
  constructor() {
    super();
  }
  write(data) {
    this.emit('data', data);
  }
}

const stream = new MyStream();

stream.on('data', (data) => {
  console.log(`Received data: "${data}"`);
});
stream.write('With ES6');
cmac
  • 3,123
  • 6
  • 36
  • 49
9

Using utility.inherits can also help you decouple the child from the parent.

Instead of calling the parent explicitly, you can use super_ to call the parent.

var BaseModel = require('relative/or/absolute/path/to/base_model'),
util = require('util');

function UserModel() {
   this.super_.apply(this, arguments);
}

util.inherits(UserModel, BaseModel);

utility.inherits source:

var inherits = function (ctor, superCtor) {
ctor.super_ = superCtor;
ctor.prototype = Object.create(superCtor.prototype, {
    constructor: {
        value: ctor,
        enumerable: false
        }
    });
};
Ivan V.
  • 7,593
  • 2
  • 36
  • 53
  • 2
    Please, note, that if you use util.inherits you should use UserModel.super_.apply(this, arguments); instead of this.super_.apply(this, arguments); – Gleb May 24 '16 at 12:14