Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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?

share|improve this question
    
Why not initialize statics outside? Don't need the if check then. –  Esailija Apr 19 '13 at 10:36
    
Don't try to be fancy, just do what all the boring people are doing and go with pllee's answer. People will shun you for doing fancy things when there is an ideomatic way to accomplish the goal. –  mortalapeman Aug 18 '13 at 22:58

1 Answer 1

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}
share|improve this answer
    
If you call this.statics.method() it does not apply to the instance. And you can do exactly the same with yours: this.constructor.statics.method(). Yours is just harder to inherit and use. –  Esailija Apr 20 '13 at 10:13
    
@Esailijav I don't think it should apply to the instance. The whole point in having statics is so that instances don't have to be created to use the functionality. Inheritance can get tricky but you can argue that you should never have to inherit statics. –  pllee Apr 20 '13 at 16:57
    
I am saying it doesn't apply to the instance and that in both cases you can refer to statics easily from an instance. And in neither does instance have to be created, as long as he moves it outside like I suggested in a comment to the question. –  Esailija Apr 20 '13 at 17:29
    
@Esailija What do you mean the statics won't apply to the the instance, they are being placed on the prototype. I updated my answer to say more clearly why I don't like the approach. –  pllee Apr 20 '13 at 18:47
    
Because it applies to the statics object, not to the instance. And I said that he must move the initialization outside constructor. –  Esailija Apr 20 '13 at 20:44

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.