views:

78

answers:

1

In his sitepoint article about javascript inheritance, Harry Fuecks explains a way of implementing inheritance as follows:

    function copyPrototype(descendant, parent) {
    var sConstructor = parent.toString();
    var aMatch = sConstructor.match( /\s*function (.*)\(/ );
    if ( aMatch != null ) { descendant.prototype[aMatch[1]] = parent; }
    for (var m in parent.prototype) {
        descendant.prototype[m] = parent.prototype[m];
    }
};

While I understand his code, one question comes to mind - why not remove the for loop and simply do this:

 function copyPrototype(descendant, parent) {
    var sConstructor = parent.toString();
    var aMatch = sConstructor.match( /\s*function (.*)\(/ );
    if ( aMatch != null ) { descendant.prototype[aMatch[1]] = parent; }
    descendant.prototype = parent.prototype;
};

Thanks.

+3  A: 

Assigning the prototype of one function to another would only assign a reference to the original prototype; both would be sharing the same prototype object. Iterating through the prototype creates a shallow copy of all its members.

Alex Barrett
Wouldn't that be what is wanted when inheriting from another object? Shouldn't any changes to the parent be reflected in the descendants?
jd
Under some circumstances, yes. But you certainly don't want changes to the descendant reflected in the parent.
Alex Barrett
Instead of assigning the prototype of one function to another I assign the prototype of my "subclass" function to a new MyParentClass() as outlined on page 169 of the Javascript Rhino book. Is that wrong/bad?PositionedRectangle.prototype = new Rectangle();
Matthew Lock
**@Matthew Lock:** This is clever technique making use of the prototype model. When using the `new` operator on a function, an `Object` is created and the members of the constructor's prototype are copied to that object. By using this new (entirely separate) object as our descendent's prototype, we have effectively created a copy of the original prototype.
Alex Barrett
Does that mean that the for loop in the question above can just be replaced by descendant.prototype = new parent(); ?
jd
**@Soca:** The downside to using the `new Parent()` approach is that the parent's constructor _may_ have side-effects. Initializing a concrete `Rectangle` is one thing - you know exactly what's happening - but when you are creating a generic inheritance model as in your original question, you cannot be sure that it's completely safe to do so.
Alex Barrett