2

When using inheritance, what is the difference and which approach would be better between ChildObject.prototype = new ParentObject(); or ChildObject.prototype = ParentObject.prototype;.

I have seen ChildObject.prototype = new ParentObject(); in a Douglas Crockford example.

1
  • The 1st one adds ParentObject's in-constructor-defined own methods/properties to ChildObject's prototype, the 2nd one doesn't because it never executes the constructor. Commented Sep 15, 2015 at 17:59

3 Answers 3

4

Neither of those.

Instead:

ChildObject.prototype = Object.create(ParentObject.prototype);
ChildObject.prototype.constructor = ChildObject;

combined with this line at the beginning of ChildObject:

ParentObject.call(this/*, appropriate args if any*/);

or if passing along all args:

ParentObject.apply(this, arguments); // `arguments` literally -- it's provided by the JavaScript engine

The problem with ChildObject.prototype = new ParentObject(); is that it won't work if ParentObject expects arguments, as many (most?) constructors do. So the pattern doesn't work in a common (possibly majority) case.

The problem with ChildObject.prototype = ParentObject.prototype; is that then you have both of them pointing at the same object. So setting a property on ChildObject.prototype makes it show up on instances of ParentObject (since you've just set it on ParentObject.prototype as well).

The Object.create version defers calling ParentObject until you have an object to initialize, but gives you an object on which you can put the things specific to ChildObject instances. (The constructor backlink is to make the replacement object look like the default one ChildObject originally had; that didn't used to matter much, but it's actually used now by ES6 in some cases, and some libs used it before even if ES5 and earlier didn't [they just put it there].)

Finally: The single-argument version of Object.create can be shimmed for obsolete browsers from before 2009 when it was added in ES5, or you can use a factory function instead if you don't like partially-shimming things:

function objectCreate(proto) {
    function ctor() { }
    ctor.prototype = proto;
    return new ctor;
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much for the explanation.
3

We usually use prototypes to supply methods - to avoid duplicating the same function for each instance of class. In other words, for something like...

ChildObject.prototype.foo = function() {
  console.log('foo');
};

Now you probably see the problem with the second approach: modifying ChildObject.prototype will modify ParentObject.prototype as well (it's the same object after ChildObject.prototype = ParentObject.prototype line). That means all ParentObject in this example will have foo method available to them. Actually, it's not even correct to say that ParentObject is parent of ChildObject - both have the same prototype chain.

Yet there's another nasty side effect. Consider this:

function ParentObj() {}
function ChildObj() {}
ChildObj.prototype = ParentObj.prototype;
var i = new ParentObj();
console.log(i); // ParentObj {}
var j = new ChildObj();
console.log(j); // ParentObj {}

See, both prototypes, as they are the same object, have the same constructor property. So to distinguish between those, we'll have to introduce some flags in the constructor functions, essentially overriding the already existing mechanism.

2 Comments

If I understand correctly, doing ChildObject.prototype = ParentObject.prototype will cause that if one augments the prototype of ChildObject, it will augment the ParentObject's prototype as well?
Of course, as both names resolve to the same object.
2

If you do

ChildObject.prototype = ParentObject.prototype;

then your parent and child have the same prototype. With the latter,

ChildObject.prototype = new ParentObject();

the child's prototype is the parent itself.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.