Search code examples
javascriptinheritancenamespacesprototype-programminghoisting

Setting up standard JavaScript prototypal inheritance within a namespace?


The standard prototypal inheritance in JavaScript is as follows:

function Animal() {
    this.legs = 0;
}
Animal.prototype.move = function () {
    alert("I'm moving!");
}

Bird.prototype = new Animal();
Bird.prototype.constructor = Bird;
function Bird() {
    this.legs = 2;
    this.wings = 2;
}
Bird.prototype.move = function () {
    alert("I'm flying!");
}

Does the function definition for Bird have to come after the assignment of Bird's prototype and constructor. I ask this because I'm trying to do this from within a namespace, and variable hoisting is causing my code to fail. As an example:

var namespace = {};
namespace.Animal = function () {
    this.legs = 0;
};
namespace.Animal.prototype.move = function () {
    alert("I'm moving!");
};

namespace.Bird.prototype = new namespace.Animal();
namespace.Bird.prototype.constructor = namespace.Bird;
namespace.Bird = function () {
    this.legs = 2;
    this.wings = 2;
};
namespace.Bird.prototype.move = function () {
    alert("I'm flying!");
};

Thanks to hoisting the namespace.Bird.prototype assignment statement and the namespace.Bird.prototype.constructor assignment statement fail. If I move the namespace.Bird function assignment above those two lines as shown in the following code block, however, the code seems to work.

namespace.Bird = function () {
    this.legs = 2;
    this.wings = 2;
};
namespace.Bird.prototype = new namespace.Animal();
namespace.Bird.prototype.constructor = namespace.Bird;

However, I don't know if there's a specific reason why most resources show the original order rather than having the function assignment come first.

Can someone please clarify?

Thanks!


Solution

  • The reason has to do with parse-time availability of functions and runtime availability of functions.

    For example:

    var afunc = asdf;
    function asdf(){} 
    

    is the same as

    function asdf(){} 
    var afunc = asdf;
    

    But,

    var afunc = asdf;
    var asdf = function(){};
    

    is not the same as

    var asdf = function(){};
    var afunc = asdf;
    

    Does that make sense why?

    Also, the answers to this question would probably help you

    var functionName = function() {} vs function functionName() {}