40

Possible Duplicate:
Calling base method using JavaScript prototype

I want to inheritance object that will override function in javascript.

From the method I want to call to the base method. In this case I inherit object reader from Person and now I want to override the function getName meaning that in reader first I want to call the function on Person and then to do some changes.

<script>
    /* Class Person. */
    function Person(name) {
        this.name = name;
    }
    Person.prototype.getName = function() {
        return this.name;
    }

    var reader = new Person('John Smith');
    reader.getName = function() {
        // call to base function of Person, is it possible?
        return('Hello reader');
    }
    alert(reader.getName());
</script>
Community
  • 1
  • 1
user1365697
  • 5,819
  • 15
  • 60
  • 96

4 Answers4

41

Vincent answered your direct question but here is what you would do if you would like to set up a true inheritance hierarchy where you can further extend Reader.

Create your person class:

function Person(name) {
    this.name = name;
}

Person.prototype.getName = function(){
    alert('Person getName called for ' + this.name);
    return this.name;
}

Create a Reader class as well:

function Reader(name) {
    // Calls the person constructor with `this` as its context
    Person.call(this, name);
}

// Make our prototype from Person.prototype so we inherit Person's methods
Reader.prototype = Object.create(Person.prototype);

// Override Persons's getName
Reader.prototype.getName = function() {
    alert('READER getName called for ' + this.name);
    // Call the original version of getName that we overrode.
    Person.prototype.getName.call(this);
    return 'Something';
}
Reader.prototype.constructor = Reader;

And now we can repeat a similar process to extend Reader with say a VoraciousReader:

function VoraciousReader(name) {
    // Call the Reader constructor which will then call the Person constructor
    Reader.call(this, name);
}

// Inherit Reader's methods (which will also inherit Person's methods)
VoraciousReader.prototype = Object.create(Reader.prototype);
VoraciousReader.prototype.constructor = VoraciousReader;
 // define our own methods for VoraciousReader
//VoraciousReader.prototype.someMethod = ... etc.

fiddle: http://jsfiddle.net/7BJNA/1/

Object.create: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/create

Object.create(arg) is creating a new object whose prototype is what was passed in as an argument.

Edit Its been years since this original answer and now Javascript supports the class keyword which works as you'd expect if you're coming from language like Java or C++. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes

Matt Wonlaw
  • 12,146
  • 5
  • 42
  • 44
  • 1
    this should have been the selected answer, it is clear and shows exactly how virtual inheritance in javascript functions using prototypes which is vague in many other answers – daniel Aug 31 '19 at 02:11
  • Wanted to solve a similar problem with an "ancient" version of JS and not using classes. The issue was a method defined as a property and not on the prototype. The .call() was the missing part of solving it without using some transpiler and ending up with messy code. – Pjotr Oct 26 '22 at 17:54
35

Since you are correctly overriding the function on the object itself and not on its prototype, you can still call the prototype function with your object.

reader.getName = function() {
    var baseName = Person.prototype.getName.call(this);
    ...
}
Vincent Robert
  • 35,564
  • 14
  • 82
  • 119
  • 6
    To have it more dynamically, use `Object.getPrototypeOf( this ).getName.call( this );` if ES5 is available. – jAndy Jul 18 '12 at 13:17
  • 2
    I would use Person.prototype.getName.apply(this, arguments) so you don't lose any arguments. Unless you specifically don't want to pass the arguments. – Dmitri R117 Feb 20 '17 at 19:19
5

I use this technique from John Resig to get inheritance and method overriding. It even lets you access to the overridden method by calling this._super().

http://ejohn.org/blog/simple-javascript-inheritance/

Absolom
  • 1,369
  • 1
  • 13
  • 28
2

This is one way to do it:

function Person(name) {
this.name = name;
}
Person.prototype.getName = function(){
return this.name;
}

var reader = new Person('John Smith');
reader.oldGetName = reader.getName;
reader.getName = function() {
//call to base function of Person , is it possible ?
    return this.oldGetName();
}
alert(reader.getName());​

http://jsfiddle.net/fXWfh/

Paddy
  • 33,309
  • 15
  • 79
  • 114