Search code examples
javascriptecmascript-5

How to Add Static Members in EcmaScript 5


I want to add a static function to a class in EcmaScript 5 JavaScript. My class definition looks as follows:

var Account = {};

Object.defineProperty(Account, 'id', {
    value : null
});

And I would create a new instance like this:

var theAccount = Object.create(Account);
theAccount.id = 123456;

Now I want to add a static function to the Account class. If I had created the Account class using a constructor function and the prototype property like this:

var Account = function () {
    this.id = null;
};

...I could just do:

Account.instances = {};

Account.createInstance = function () {
    var account = new Account();
    account.id = uuid.v4();
    Account.instances[account.id] = account;
    return account;
};

But since I am using Object.defineProperty and not the prototype property to add members, Account.instances and Account.createInstance would also be instantiated when calling Object.create and therefore be properties of the instance.

How do i add a static member to a class when using EcmaScript 5 style object creation?


Solution

  • You can't.

    My class definition looks as follows var Account = {};

    That's not a class (if we would call the classical model like that), but just a prototoype object. And as you only have that, you will need to use other variables for static members like an instances-cache or a create function:

    var Account = {...};
    var instances = [];
    function createAccount(){...}
    

    You could namespace them, of course:

    var Account = {
        proto: {...},
        instances: [],
        instantiate: function create(){...}
    };
    

    ...but that looks very close to the classical pattern, doesn't it? The only difference would be that you had a create function on a namespace object instead of a constructor function as the namespace object.

    You might also be interested in the question Object.create Prototype Chains, where I have discussed a full inheritance model working like that, with create and inherit methods that all "class objects" inherit from a base.


    Further answer on your question in the comments:

    Doesn't Object.create make the new operator obsolete in EcmaScript 5?

    No. The new keyword does two things: Set up the prototype chain of the new instance, and apply the the constructor function. Object.create does only the first thing, so you can use it when you dont need a function (or dont want it to execute).

    In your case, you have such a function, so the classical model wouldn't be wrong here as well. See also Using "Object.create" instead of "new".