3

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.

1

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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/

1 Comment

Not as pretty as super.foo(), but it sure works. Thanks a lot!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.