19

Here is code, I've been struggling for hours with that, idea is to keep track of how many instances is created, but also make possible to call static method and change/update static member. There is similar question, but I can't implement any solution to my problem.

  // object constructor
function Foo() {
    this.publicProperty = "This is public property";
}
// static property
Foo.staticProperty = "This is static property";

// static method
Foo.returnFooStaticProperty = function() {
    return Foo.staticProperty;
};


console.log("Static member on class: " + Foo.staticProperty); // This is static property


console.log("Result of static method: " + Foo.returnFooStaticProperty()); //This is static property

var myFoo = new Foo();
console.log("myFoo static property is: " + myFoo.staticProperty); // undefined

For sake of simplicity I have changed constructor and member names here. I think it is obvious what happening. I want both of constructor object and instance share same static property.

I can access static member on constructor object, but on instance I got undefined.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Alan Kis
  • 1,790
  • 4
  • 24
  • 47

4 Answers4

19

You can try to get access to static property via constructor

console.log(myFoo.constructor.staticProperty);
romik
  • 490
  • 3
  • 7
9

EDIT: I re-read your question, and this code solves your actual problem as stated:

JavaScript:

function Foo() {
    this.publicProperty = "This is public property";
    Object.getPrototypeOf(this).count++;
}
Foo.prototype.count = 0;

console.log(new Foo().count, new Foo().count, Foo.prototype.count);

This does not decrement the count automatically though if the object is freed up for garbage collection, but you could use delete then manually decrement.

Xitalogy
  • 1,592
  • 1
  • 14
  • 17
  • Yes, I have seen that now. Point is that I have share same variable between object constructor and it's instance, but also be able to run static method, or method on object constructor. And in your final log call staticProperty on instance is undefined. – Alan Kis Oct 19 '13 at 21:57
  • 1
    I showed that myFoo.staticProperty was undefined in the log on purpose to illustrate that without a "kludge" function like myFoo.returnFooStaticProperty() I do not think you can access the static member from the instance object. The "kludge" function works, but can you explain why you want to share the static variable between the class and its instances? Maybe rethinking the way it works with prototypes (and inheritance) in mind would be profitable? – Xitalogy Oct 19 '13 at 22:44
  • yes, as I mentioned prototype approach confuses me sometimes. Point is that static members is shared between all instances and class/constructor function itself, but it's value is stored in one place, which means that object instances don't inherit that value. And that is where prototype comes on scene. Only difference between yours and mors answer is that I need to call method on constructor function. – Alan Kis Oct 19 '13 at 22:53
  • 1
    @AlanKis I re-read your question, and realized no one actually addressed what you are trying to accomplish. I believe I have done this now. – Xitalogy Oct 19 '13 at 23:09
  • Yes, I have made both solution work, with one small addition to yours, and thats exactly what I want: `Foo.countCount = function() { return Foo.prototype.count += 1; };` Wich mean that even if I call method(static method) on object constructor count keeps incrementing. `console.log Foo.countCount()); //1 console.log(Foo.countCount()); //2 console.log(Foo.countCount());` //3 Now this prototypal inheritance is much clearer to me, so finally I can go to sleep. – Alan Kis Oct 20 '13 at 00:13
  • Yay! I think though if you just call Foo() without new and throw away the undefined value that is returned, it will increment Foo.prototype.count without the need for a separate method, although that could be wasteful for a large constructor and if the constructor had side effects other than incrementing count it could be harmful. – Xitalogy Oct 20 '13 at 00:19
  • 1
    Fiddle link is broken. – Artemis Nov 21 '20 at 19:53
  • Thanks, @Artemis - I removed the link – Xitalogy Nov 23 '20 at 07:10
2

Javascript is prototype based. In other words, all instances of an object share the same prototype. You can then use this prototype to put static shared properties:

function Foo() {
  this.publicProperty = "This is public property";
}

Foo.prototype.staticProperty = "This is static property";

var myFoo = new Foo();
console.log(myFoo.staticProperty); // 'This is static property'

Foo.prototype.staticProperty = "This has changed now";
console.log(myFoo.staticProperty); // 'This has changed now'
mor
  • 2,313
  • 18
  • 28
-2

very simplified approach:

class MyClass{
   static t
   constructor(){
      MyClass.t=this;
   }
   my1stMethod(){
      new SomeOtherClass( somevalue, function(){
        // now, here 'this' is a reference to SomeOtherClass so:
            MyClass.t.my2ndMethod();
    })
   }
 
   my2ndMethod(){
      console.log('im my2ndMethod');
      this.my3dMethod();
   }

   my3dMethod(){
      console.log('im my3dMethod');
   }
}
CodeToLife
  • 3,672
  • 2
  • 41
  • 29