Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to redefine a JavaScript class's method?

When using a constructor function in JavaScript to create a class, is it possible to redefine the class's method later?

Example:

function Person(name)
{
    this.name = name;
    this.sayHello = function() {
        alert('Hello, ' + this.name);
    };
};

var p = new Person("Bob");
p.sayHello();   // Hello, Bob

Now I'd like to redefine sayHello like this:

// This doesn't work (creates a static method)
Person.sayHello() = function() {
   alert('Hola, ' + this.name);
};

so when I create another Person, the new sayHello method will be called:

var p2 = new Person("Sue");
p2.sayHello();   // Hola, Sue
p.sayHello();    // Hello, Bob

EDIT:

I realize I could send in an argument like "Hello" or "Hola" to sayHello to accomplish the different output. I also realize I could simply assign a new function to p2 like this:

p2.sayHello = function() { alert('Hola, ' + this.name); };

I'm just wondering if I can redefine the class's method so new instances of Person will use the new sayHello method.

like image 649
tronman Avatar asked Jan 20 '14 20:01

tronman


2 Answers

is it possible to redefine the class's method later?

Yes. However, you must not assign the new function to a property of the Person constructor, but to the instance itself:

var p2 = new Person("Sue");
p2.sayHello();   // Hello, Sue
p2.sayHello = function() {
   alert('Hola, ' + this.name);
};
p2.sayHello();   // Hola, Sue

If you want to do this for all new instances automatically (and have not used the prototype for the method, which you easily could exchange as in @dystroy's answer), you will need to decorate the constructor:

Person = (function (original) {
    function Person() {
        original.apply(this, arguments);   // apply constructor
        this.sayHello = function() {       // overwrite method
            alert('Hola, ' + this.name);
        };
    }
    Person.prototype = original.prototype; // reset prototype
    Person.prototype.constructor = Person; // fix constructor property
    return Person;
})(Person);
like image 73
Bergi Avatar answered Sep 20 '22 03:09

Bergi


To have a different function for p2, you can just set the sayHello property of p2 :

p2.sayHello = function(){ 
    alert('another one');
}
p2.sayHello(); 

If you use prototype, then you can also change it for all instances of Person (and still you can overwrite it for a specific person) :

function Person(name)
{
    this.name = name;
};
Person.prototype.sayHello = function() {
    alert('Hello, ' + this.name);
};

var p = new Person("Bob");

// let's set a specific one for p2
p2.sayHello = function(){ 
    alert('another one');
}

// now let's redefine for all persons (apart p2 which will keep his specific one)
Person.prototype.sayHello = function(){ 
    alert('different!');
}

p.sayHello();  // different!
p2.sayHello(); // another one
like image 40
Denys Séguret Avatar answered Sep 23 '22 03:09

Denys Séguret