Object-oriented – JavaScript static methods retrieval

javascriptobject-orientedstatic methods

I have been thinking about it and wanted some feedback, recently I thought about doing it like this:

function foo(){
   if ( !foo.prototype.statics ){
       foo.prototype.statics = {
          // declare static functions/vars here
       }
   }
   if ( !(this instanceof foo) ){
        return foo.prototype.statics;
   }

   var statics = foo.prototype.statics; // shortcut
   // if it reaches here then it's an instance (new foo())
}

foo().callStaticMethod();
(new Foo()).callInstanceMethod();

Is this a good way to do it or do you think of any reason why this can be an anti-patern?

Best Answer

Those aren't static methods they are on the prototype. Instances of foo would be able to call static methods by just doing this.statics.method. True statics would be applied to just foo itself. It is also cleaner than putting logic in the constructor to handle statics.

function foo() {

}

foo.statics = {

}

console.log(new foo().statics)
//undefined
console.log(foo.statics)
// {}

The framework that we write in allows statics this way, it is a nice way to keep enums and constants. It also gets around problems that happen when instance sharing is not needed and non primatives are placed on prototype, which for some reason happens all of the time on SO. Problems arise during inheritance though since static methods defined this way won't be inherited. The inheritance problem mostly arises after due to parent classes having methods that do this.class.statics.staticFn if the class is inherited from those methods won't work but that can easily be fixed.

update

Having to invoke a function to get at the statics and having logic in the constructor to have it handle and know about it having statics is bad in my opinion. The user has to know that the statics need to be accesses by invoking a function and the constructor needs to know that it has statics and to handle the case where the new operator is not used.

Problems can arise when instances don't know that they are modifying statics. In this case lets replace the name statics with config.

function foo(){
   if ( !foo.prototype.config ){
       foo.prototype.config = {
           a: 1,
           b: 2
       }
   }
   if ( !(this instanceof foo) ){
        return foo.prototype.config;
   }
}

foo.prototype.foobar = function() {
  this.config.a = 5;
}


foo()
>Object {a: 1, b: 2}
new foo().foobar();
foo();
> Object {a: 5, b:2}
Related Topic