Search code examples
javascriptconstructorextend

Why do I need to set constructor for a extend function?


I'm trying to fully understand how 'extend' works in javascript.

Here's a simple extend function I found on google

function extend(child, parent) {

    var f = function() {}
    f.prototype = parent.prototype;


    var i;

    for( i in parent.prototype ) {
        child.prototype[i] = parent.prototype[i];
    }


    child.prototype.constructor = child;
    child.parent = parent;

}

it works, but I don't understand "child.prototype.constructor = child" part. The function still works without it.

What's the purpose of the line?


Solution

  • No. Where did you find that? It mixes two approaches:

    The classical prototype inheritance

    function inherit(child, parent) {
        var f = function() {}
        f.prototype = parent.prototype;
    
        child.prototype = new f();
        child.prototype.constructor = child;
    }
    

    This function creates a new object that inherits directly from the prototype object of the parent function. It is an old-style synonym for Object.create(). With that, a prototype chain is set up - all instances of child inherit from the parent.prototype as well. Because a new object is generated to overwrite child.prototype, the "constrcutor" property needs to be updated.

    The mixin inheritance

    This function just loops over all properties of the parent's prototype object, and copies them onto the child's prototype object. This is quite what the common helper function extend does. It does not reset the "prototype" property of the child function, but it also does not set up a inheritance chain.

    function extend(child, parent) {
        for (var i in parent.prototype ) {
            child.prototype[i] = parent.prototype[i];
        }
    }
    

    You are right, the line

    child.prototype.constructor = child;
    

    is quite useless here - the "constructor" property is not enumerable and will not be affected by the extend.

    Also, your function sets a "parent" property of the child function object to the parent function, which is not required:

    child.parent = parent;