Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 681
Max Kueng Avatar asked Jul 27 '12 11:07

Max Kueng


2 Answers

For ES 5 if you want static methods:

// A static method; this method only 
// exists on the class and doesn't exist 
// on child objects
Person.sayName = function() {
    alert("I am a Person object ;)");  
};

// An instance method; 
// All Person objects will have this method
Person.prototype.setName = function(nameIn) {
    this.name = nameIn;  
}

see @https://abdulapopoola.com/2013/03/30/static-and-instance-methods-in-javascript/

like image 73
Combine Avatar answered Oct 06 '22 00:10

Combine


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".

like image 36
Bergi Avatar answered Oct 06 '22 01:10

Bergi