0

I want to invoke a method from a parent class as part of a child class method in JavaScript, using pseudoclassical pattern. I've seen code samples where the parent class method is invoked by 'Parent.prototype.parentMethod.call(this)' as below:

function Parent(arg1) {
  this.arg1 = arg1;
}

Parent.prototype.parentMethod = function() {
  return `Argument 1 is: ${this.arg1}`;
};

function Child(arg1, arg2) {
  Parent.call(this, arg1);
  this.arg2 = arg2;
}

Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;

Child.prototype.childMethod = function() {
  return `${Parent.prototype.parentMethod.call(this)} and Argument 2 is: ${this.arg2}`;
};

In implementing the child method, why is it necessary (or desirable) to do 'Parent.prototype.parentMethod.call(this)' instead of just 'this.parentMethod'? Shouldn't the prototype chain make it possible to do 'this.parentMethod'?

  • Can I ask where you got this original snippet from? Perhaps there is some context around the source which would indicate why it is being called that way. However, from what you have posted alone, I would say that it is neither necessary nor desirable to invoke the parent method in that way. As you note, you can just use `this.parentMethod()`, which is much shorter and IMO more clear in it's intention. – CRice Jun 07 '21 at 22:02
  • You need to read, [How this works in Javascript](https://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work) – DecPK Jun 07 '21 at 22:03

1 Answers1

0

Shouldn't the prototype chain make it possible to do this.parentMethod()?

Yes, this is possible.

Why is it necessary (or desirable) to do Parent.prototype.parentMethod.call(this) instead of just this.parentMethod?

It's desirable when you want to call that specific method (the parent's implementation), not the possibly overwritten this.parentMethod.

This is essential (necessary) when overriding the method yourself, and you want to call the overridden method:

function Parent(arg1) {
  this.arg1 = arg1;
}
Parent.prototype.method = function() {
  return `Argument 1 is: ${this.arg1}`;
};

function Child(arg1, arg2) {
  Parent.call(this, arg1);
  this.arg2 = arg2;
}
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
Child.prototype.method = function() {
  return `${Parent.prototype.method.call(this)} and Argument 2 is: ${this.arg2}`;
};

Calling this.method() would result in recursion (and a stack overflow) instead.

Notice the modern way to write this is

class Parent {
  constructor(arg1) {
    this.arg1 = arg1;
  }
  method() {
    return `Argument 1 is: ${this.arg1}`;
  }
}
class Child {
  constructor(arg1, arg2) {
    super(arg1);
    this.arg2 = arg2;
  }
  method() {
    return `${super.method()} and Argument 2 is: ${this.arg2}`;
  }
}

super.method() does exactly the same as the old syntax did.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375