How to access static member on instance?
Asked Answered
S

4

22

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.

Septavalent answered 19/10, 2013 at 20:6 Comment(0)
J
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.

Juvenile answered 19/10, 2013 at 20:38 Comment(8)
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.Septavalent
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?Juvenile
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.Septavalent
@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.Juvenile
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.Septavalent
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.Juvenile
Fiddle link is broken.Roldan
Thanks, @Artemis - I removed the linkJuvenile
N
20

You can try to get access to static property via constructor

console.log(myFoo.constructor.staticProperty);
Na answered 19/10, 2013 at 20:14 Comment(3)
What exactly is happening in that case? Am I pointing that constructor of myFoo is Foo, because is static property binded to constructor function Foo?Septavalent
Use new ClassName().constructor.staticPropertyDemeter
I don't know if the original question title was edited, but this is the only correct answer to how to get a static member value from an instance (i.e. without knowing the class name).Puiia
J
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.

Juvenile answered 19/10, 2013 at 20:38 Comment(8)
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.Septavalent
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?Juvenile
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.Septavalent
@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.Juvenile
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.Septavalent
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.Juvenile
Fiddle link is broken.Roldan
Thanks, @Artemis - I removed the linkJuvenile
S
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'
Saiz answered 19/10, 2013 at 20:23 Comment(2)
But in that case, Foo() object construct loose that static member.Septavalent
@AlanKis, it does not. You can always refer to it using this.prototype.staticProperty.Saiz
M
-3

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');
   }
}
Midget answered 20/1, 2023 at 7:56 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.