1

I'm looking to do something a little bit fancy with constructor functions in Javascript, and I'm not quite sure how to do it.

I want to be able to define Constructor functions, and then pass them into another function (a "modifer") like this:

function OriginalConstructor() {
    // Do constructor things here
    // Like defining methods and properties
}

NewConstructor = modifyConstructor(OriginalConstructor);

And the resulting "NewConstructor" should be functionally equivalent to this:

function NewConstructor(id, data) {
    this.id = id;
    this.data = data;
    // Do stuff from the original constructor here
    // i.e. the same methods and properties defined in the original constructor
}

Does anybody know how to go about creating the "modifyConstructor" function?

Joshua Wise
  • 613
  • 4
  • 15
  • Not sure I get it, you want to return a new constructor with the same methods and prototype, or just return a new instance of the passed constructor ? – adeneo Aug 22 '14 at 16:14
  • Sounds like classic subclassing with a super() call. Or should they share the same prototype? – Bergi Aug 22 '14 at 16:30
  • see also [Is it possible to redefine a JavaScript class's method?](http://stackoverflow.com/a/21243884/1048572) – Bergi Jul 30 '15 at 12:20

2 Answers2

3

You create a function that sets the properties as you defined and calls the original constructor. For example:

function modifyConstructor(Constr) {
    function NewConstructor(id, data) {
        this.id = id;
        this.data = data;

        // Call original constructor
        Constr.apply(this, Array.prototype.slice.call(arguments, 2));
    }
    // Setting the constructor property might not be a good idea depending on
    // the use case
    NewConstructor.prototype = Object.create(Constr.prototype, {
        constructor: {value: NewConstructor, writable: true, configurable: true}
    });
    return NewConstructor;
}

This basically implements NewConstructor as a subclass of whatever Constr is.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
0

Your example looks like a bad practice.

This way it is much easier to maintain,

I'd go like so:

function OriginalConstructor(id, number){

   this.id = id;
   this.number = number;

}
var Obj = new OriginalConstructor();

function newConstructor(Obj){

   this.id = Obj.id;
   this.number = Obj.number * 2;

}

newObject = new newConstructor(Obj);

What you receive from that is: an Obj that was originally created by original constructor, and it's data and state never changed and a newObject which was created by the modifiedConstructor which modifies an object based on a new constructor.

Linial
  • 1,154
  • 9
  • 22
  • It seems it should be `new newConstructor(Obj);`. You should point out though that `newObject` has none of the other properties that `Obj` might have. So it's a different result from what the OP described in their question. – Felix Kling Aug 22 '14 at 16:22
  • Fixed the first one, About the second one, what do you mean newObject has none of the other properties that Obj might have, it was created based on the data that Obj holds. – Linial Aug 22 '14 at 16:24
  • If there are any properties set on `OriginalConstructor.prototype`, `newObject` doesn't have them. – Felix Kling Aug 22 '14 at 16:26