简体   繁体   中英

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

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.

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/

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM