0

I have an object that looks like

var customObject = function() {
    this.property = "value";
};

customObject.prototype = new otherObject();

customObject.prototype.property2 = function() {};

etc. - it's much bigger than this.

I can successfully instantiate the object by writing new customObject().

Now I would like to create a rather similar object, although a little different. This involves modifying certain properties and perhaps even adding or removing some. As in the above example, I would like it to be invokable by writing new customObject2().

I thought I could simply do:

var customObject2 = new customObject();
customObject2.prototype = customObject.prototype;
customObject2.property = "modified value";

etc.

However, when I try to instantiate it by doing new customObject2() I receive an error, stating that the customObject2 is not a function.

I hope I could illustrate well enough as to what pattern I desire to create. What approach should I take to create such a pattern?

user2180613
  • 699
  • 6
  • 20
  • Well looking at your code, you're doing `customObject2 = new customObject()`. That should explain why it's not a function – Jani Hartikainen Jul 26 '13 at 22:15
  • Is there some quick way to get what I need? Or am I supposed to manually create a `var customObject2 = function() {};` and loop over all the direct properties of the original `customObject` to assign them to the `this` of `customObject2`? – user2180613 Jul 26 '13 at 22:18

3 Answers3

1

If customObject is not a host object (i.e. won't give you an illegal invocation error if you try to call it differently to expected) you can apply the constructor to a different this Object;

var customObject2 = function () {
    customObject.call(this); // construct as if `customObject`
    // now do more stuff
    this.anotherProperty = 'foo';
};
customObject2.prototype = Object.create(customObject.prototype);
    // inherit prototype but keep original safe

new customObject2();

Backwards compatible Object.create

function objectWithProto(proto) {
    var f;
    if (Object.create) return Object.create(proto);
    f = function () {};
    f.prototype = proto;
    return new f();
}
Paul S.
  • 58,277
  • 8
  • 106
  • 120
  • Do you have an alternative for the Object.create that is compatible with older browsers as well? Oh, hang on: http://stackoverflow.com/questions/5199126/javascript-object-create-not-working-in-firefox – user2180613 Jul 26 '13 at 22:29
  • Thanks, this is the short solution I was looking for and it avoids simply extending `customObject` – user2180613 Jul 26 '13 at 22:36
  • 1
    @user2180613 But this is also extending customObject, it's just a different technique. – bfavaretto Jul 27 '13 at 00:04
  • @bfavaretto iirc coffeescript uses this style with their `extend` keyword – Paul S. Jul 27 '13 at 02:25
0

I think this should answer your question. Basically, the new keyword is returning an object and not a function.

Community
  • 1
  • 1
Ryan George
  • 186
  • 9
  • No it doesn't. I know very well what the keyword does, but I was wondering if there is a quick way to copy an object and have it remain "instantiatable". – user2180613 Jul 26 '13 at 22:20
0

Why are you not using the same formula you used the first time? For example:

var customObject2 = function(){};
customObject2.prototype = new customObject();
customObject2.property = "modified value";
new customObject2(); // works!

All properties of customObject will be inherited by the instances of customObject2 through the prototype chain.

bfavaretto
  • 69,385
  • 15
  • 102
  • 145