41

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>
0

4 Answers 4

42

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

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

2 Comments

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
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.
36

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);
    ...
}

2 Comments

To have it more dynamically, use Object.getPrototypeOf( this ).getName.call( this ); if ES5 is available.
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.
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/

Comments

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/

1 Comment

Vincent's answer seems to be much neater than this - probably a better way to go...

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.