leela
leela

Reputation: 15

Javascript/Node.js: ES5 child class instance accessing parent class method

I am trying to access parent's method in child's constructor as following:

file1.js

var ParentClass = function(arg) {
    this.arg = arg;
    this.result = {};
};

ParentClass.prototype = {
    constructor: ParentClass,
    isActive: function(condition) {
        return new Date(condition.valid).getTime() <= Date.now())
    }
};

module.exports = ParentClass;

file2.js

var ParentClass = require('file1');

var ChildClass= function(arg) {
    ParentClass.apply(this, arguments);
    this.init();
};

ChildClass.prototype = Object.create(ParentClass.prototype);
ChildClass.prototype.constructor = ChildClass;

ChildClass.prototype = {
    init: function() {
        this.result = this.arg.validity
        .filter(function(elem) {
            return this.isActive(elem)
        }.bind(this));
    }
}

module.exports = ChildClass;

file3.js

var ChildClass= require('file2.js');
var instance = new ChildClass(param);

initializing such instance gives me

TypeError: this.isActive is not a function
  at Object.<anonymous> (file2.js)
  at Array.filter (native)
  at Object.ChildClass.init (file2.js)

Help and explanation appreciated. Thank you!

Upvotes: 0

Views: 825

Answers (2)

jfriend00
jfriend00

Reputation: 707258

You have two separate assignments to ChildClass.prototype. One will override the other. Instead, you need to first initialize your prototype with Object.create() as you are doing and then you need to ADD new methods to it, not assign to the whole prototype, thus replacing everything you just put there.

These are the two conflicting statements:

ChildClass.prototype = Object.create(ParentClass.prototype);

ChildClass.prototype = {...};

One common way to fix this is to use Object.assign() to copy your methods onto the existing prototype:

Object.assign(ChildClass.prototype, {
    init: function() {
        this.result = this.arg.validity
        .filter(function(elem) {
            return this.isActive(elem)
        }.bind(this));
    }
});

This will copy each of your methods over to the already existing prototype object and this method is more commonly used when you have lots of methods.

You can also just assign the new methods one at a time (more commonly used when you have just a few methods):

ChildClass.prototype.init = function() {
    this.result = this.arg.validity.filter(function(elem) {
        return this.isActive(elem)
    }.bind(this));
}

Upvotes: 3

mhodges
mhodges

Reputation: 11116

You are redefining ChildClass.prototype as a new object, which overwrites your assignment using Object.create() a few lines prior. Instead, simply define the init method on it.

Try this:

var ParentClass = function(arg) {
  this.arg = arg;
  this.result = {};
};

ParentClass.prototype = {
  constructor: ParentClass,
  isActive: function(condition) {
    return new Date(condition.valid).getTime() <= Date.now();
  }
};

var ChildClass = function(arg) {
  ParentClass.apply(this, arguments);
  this.init();
};

ChildClass.prototype = Object.create(ParentClass.prototype);
ChildClass.prototype.constructor = ChildClass;
ChildClass.prototype.init = function() {
  this.result = this.arg.validity
    .filter(function(elem) {
      return this.isActive(elem);
    }.bind(this));
};


var instance = new ChildClass({
  validity: [{
    valid: "01/01/17"
  }]
});

console.log(instance);

Upvotes: 0

Related Questions