Search code examples
javascriptoopprototype-chain

when is a method on an object's prototype chain callable?


Consider this code...

var org = {};

org.Organization = function() {

    var app = null;
    function setupApplication() {};

    return {
        init : function() {
            console.log("init");
        }
    }
};

org.Organization.prototype = {
    status : function() {
        console.log("status");
    }
};

var myOrg = new org.Organization();
myOrg.init();      // outputs "init"
myOrg.status();    // TypeError: Object #<Object> has no method 'status'

... the status() method does not exist and I can't call it :( However, if I were to remove the return { ... } like so...

var org = {};

org.Organization = function() {

    var app = null;
    function setupApplication() {};
};

org.Organization.prototype = {
    status : function() {
        console.log("status");
    }
};

var myOrg = new org.Organization();
myOrg.init();      // TypeError: Object #<Object> has no method 'init
myOrg.status();    // outputs "status"

... then the status() method does exist and I can call it with no problems. Why is this happening? Why can a method on the prototype chain be called only when original object has no return { ... }? Does the return { ... } overwrite or take precedence over the methods on the prototype chain?


Solution

  • When you use return obj in a function constructor, it will return that actual object, not the object that has been constructed internally. If you want it to work correctly, simply define init within the constructor like so:

    this.init = function() { };
    

    To give a few more details: when you call new Func, what happens internally is that a new object (with the prototype set to the function's prototype) is created and the constructor function is called with the object set as this. At the end of the constructor, the same object is returned, unless you return another object manually, in which case that object will be returned, which will obviously not have the same prototoype.