Shaun
Shaun

Reputation: 35

Is it possible to call an overridden method in an instance of child class ES 2015?

I recently saw a similar question while looking at technical interview questions and it got me thinking about object inheritance more generally in JavaScript.

Here is some simple code:

class Car {
  constructor(make,model) {
    this.make = make
    this.model = model
  }

  emitsCarbon() {
    return true
  }

}

class Hybrid extends Car {
  constructor(...args) {
    super(...args)
  }
  emitsCarbon() {
    return false
  }
}

let car1 = new Hybrid('toyota', 'prius')

car1.emitsCarbon() // returns false

What I am curious about is if there is a way to call the original emitsCarbon() method that returns true (from the parent class) in the instance of child class?

My assumption would be no, once it is overridden, I would have to override the method again in the instance of car1 to get it to return true when the function is called.

The lack of knowledge I am seeking to fill is: in JavaScript is it possible to refer back up level in class inheritance and see all the parent class properties (methods, etc.) given an instance of a child class. It looks like this is possible in other languages (e.g., java), however, I do not have as much experience with those languages as much.

Lastly, whether this is useful, i.e., whether one should be more careful about overriding properties that should not be overridden, I am less certain. I think that one shouldn't. However, it is useful to better understand moving up a level in classes and class inheritance hierarchy in general.

This is not a duplicate of: How to call a parent method from child class in javascript?

I understand the calling of a parent method in a child class, however, I do not understand the calling (if at all possible, which it seems not) of a parent method in a child instance.

Upvotes: 3

Views: 2214

Answers (4)

mbojko
mbojko

Reputation: 14679

It's JavaScript, so you can. There's no classes anyway, just prototypal inheritance with some syntactic sugar over it.

Which one do you want to call: Car's emitsCarbon specifically? That'll be

Car.prototype.emitsCarbon.call(car1);

Your object's class' direct ancestor class' emitsCarbon in general?

car1.__proto__.__proto__.emitsCarbon.call(car1);

(You're not supposed to directly access __proto__, but there's nothing actually stopping you besides the general good practice and guidelines).

Also, hybrids do emit carbon. Just a side note.

Upvotes: 4

Danish Shakeel
Danish Shakeel

Reputation: 227

When a child overrides parent methods, it will always use the overriden version unless you don't use the 'super' keyword in the method definition of the child itself.

Calling a parent method through a child object which is already overriding the method is not possible this way.

Upvotes: 0

junvar
junvar

Reputation: 11574

The other answer is good for when you can modify the child class.

But since the original post mentions '...instance of child class', as opposed to 'given the child class', then you can do similarly even when you can't modify the child class by using <ParentClass>.prototype.<methodName>.

class A {
  foo () {
    return 0;
  }
}

class B extends A {
  foo () {
    return 1;
  }
}

let b = new B();
console.log(b.foo()); // 1
console.log(A.prototype.foo()); // 0

For methods that require a this context, use call to invoke.

class A {
  constructor(f) {
    this.f = f;
  }

  foo(ff) {
    return this.f + ff + 1;
  }
}

class B extends A {
  foo(ff) {
    return this.f + ff + 2;
  }
}

let b = new B(10);
console.log(b.foo(5)); // 17
console.log(A.prototype.foo.call(b, 5)); // 16

Upvotes: 0

Jared Smith
Jared Smith

Reputation: 21926

I can't believe this isn't a duplicate, but I can't find it (all existing Q/A's deal with old-style constructor functions), so...

Just use super:

class A {
  foo () {
    return 0;
  }
}

class B extends A {
  foo () {
    return 1;
  }

  bar () {
    return super.foo();
  }
}

const b = new B();
b.foo() // 1
b.bar() // 0

There are some limitations, using super will not allow you to modify read-only properties.

See the MDN article for more details.

Upvotes: 0

Related Questions