Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a javascript object override its parent method and call it in that method?

Tags:

javascript

Imagine the following scenario:

I have two classes: Parent and Child. Parent has a method foo(). Child wants to override foo(), and within do whatever foo() did in Parent's foo().

In any other programming language i would just do something like

foo(){
  super.foo();
  //do new stuff
}

But in javascript there's no such thing. Here's a short version of my code:

function Parent( name, stuff ){
  this.name = name;
  this.stuff = stuff;
}

Parent.prototype = {        
  foo: function(){ 
    console.log('foo');
  }
}

function Child(name, stuff, otherStuff ){
  Parent.call(this, name, stuff);
  this.otherStuff = otherStuff;
}

Child.prototype = new Parent();
Child.prototype.foo = function(){

  ???//I want to call my parents foo()! :(
  console.log('bar');

}

What I want to achieve is that when an instance of Child calls foo() i can get foobar in the console.

Thanks!

PS: please, no JQuery, PrototypeJS, ExtJs, etc... This is a Javascript project and also a learning exercise. Thank you.

like image 442
whtlnv Avatar asked Jan 21 '26 01:01

whtlnv


2 Answers

First of all, your implementation of inheritance is not great. I propose the following change:

// Child.prototype = new Parent(); // bad because you instantiate parent here
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;

With that in mind, i wrote this helper function:

function base(object, methodName) {
  var proto = object.constructor.prototype;
  var args = Array.prototype.slice.call(arguments, 2);
  while (proto = Object.getPrototypeOf(proto)) 
    if (proto[methodName])  
      return proto[methodName].apply(this,args);
  throw Error('No method with name ' + methodName + ' found in prototype chain');
}

// usage:

Child.prototype.foo = function(){
  base(this, 'foo', 'argument1', 'argument2');  
  console.log('bar');
};

It has slightly more than what you wanted, in that you don't have to wonder where the method is defined in the inheritance chain, it will go all the way up to the root and try to find the method. I also expanded your example a bit with a Grandparent to exhibit this issue. The foo method has been moved from the Parent to the Grandparent (and Parent inherits from Grandparent).

Grandparent demo: http://jsbin.com/iwaWaRe/2/edit

NOTE: The implementation is loosely based on Google Closure Library's implementation of goog.base.

like image 126
Tibos Avatar answered Jan 22 '26 14:01

Tibos


Its simply, you can use the prototype and use call/apply to call the parents function.

Child.prototype.foo = function(){
  Parent.prototype.foo.apply(this, arguments);
  console.log('bar');
}

Take a look: http://jsfiddle.net/J4wHW/

like image 28
Guilherme Avatar answered Jan 22 '26 16:01

Guilherme