7

I've been hunting around for a clear answer to this, and most of what pops up still relates to the old (or should I say "traditional") way of defining classes using function.

According to this SO answer,

Class properties are not supported in ES2015.

As far as I can tell, the only way to add a static variable to a class is like:

https://jsfiddle.net/abalter/fknwx3n4/

class C {

  constructor(x) {
    console.log("in constructor " + x);
    this.x = x;
    this.add(this.x);
  }

  add(x) {
    console.log("in add " + x);
    C.alist.push(x);
  }

  show() {
    console.log("in show");
    console.log(C.alist);
  }
}

// MUST be done outside of actual class definition.
C.alist = [];

c1 = new C(5);
c1.show();
c2 = new C(10);
c1.show();
c2.show();

Is this the end of the story? Just seems so strange to not be able to do it INSIDE the class definition.

12
  • Yes, that's the end of the story. There is nothing wrong with putting such properties after the class definition, btw Commented Jun 23, 2016 at 4:57
  • ES7 supports class properties. But no, that's not the end of story in ES2015. The array could be set in the constructor as the instance property. Commented Jun 23, 2016 at 4:58
  • 1
    @Vohuman: ES7 does not, and probably ES8 won't either. Commented Jun 23, 2016 at 4:58
  • 1
    @Vohuman This proposal is still on stage 1. It has been for a long time. I am not sure why it is not moving forward as it looks like a lot of people would like to see it. Commented Jun 23, 2016 at 5:31
  • 1
    @abalter: No, I meant that only C.alist = []; is the singleton object. Of course, in Java where everything is a class, you'd need an extra class to create singleton instances, in JS creating objects directly is so much simpler. Commented Jun 23, 2016 at 17:50

2 Answers 2

2

You could call a static function that initializes all the static members immediately after the class is defined, and then optionally delete that function. (Possibly resetting static variables would be a feature?)

This would allow you to keep all of your static variables inside the class declaration.

class C {
  static init() {
    C.alist = [];
  }

  constructor(x) {…}
  add(x) {…}
  show() {…}
}
C.init();
delete C.init;

Another option is to initialize static variables in the constructor, but this requires that at least one object be instantiated before the static variables can be used.

class C {
  constructor(x) {
    C.alist = C.alist || [];
    …
  }
  add(x) {…}
  show() {…}
}
Sign up to request clarification or add additional context in comments.

7 Comments

Interesting...Also a bit awkward, but at least it is in the constructor.
@abalter I have updated. Maybe you will find this other option less awkward? It would also allow you to reset all the static variables later.
I would code this.alist = [] and not C.alist = []. Why should instances share the same information? That's misusing a class.
@Vohuman Are you saying it's misusing a JS class? Because in OOP it's perfectly legal and very common.
@abalter I'll definitely put the old answer back in. I kinda prefer this though because it allows for syntax that feels a little more natural, and the only part that remains outside of the class is a bit of helper code. I was a bit unhappy with how my other solution required instantiating an object too.
|
0

If all you care about is stylistic encapsulation of the class and its static properties in one structure, you should consider using the module pattern (just like we used it in ES5 to enclose the constructor and the prototype).

In ES6, there is also Object.assign that you could use for this:

const C = Object.assign(class {
    constructor() {
        …
    }
    methods() { … }
    …
}, {
    of(x) { … },
    static_methods() {…},
    …
    static_property: …
});

3 Comments

I have mixed feelings. It works, and even allows separation of concerns to a degree, but loses much of the syntactic sugar. Would either of our solutions suffer when extending the class?
No, you still can use extends C without problems. The only syntactic sugar you lose is super when putting your static methods in the object literal, you'd have to use static static_method() { super…} in the class body for that.
In case anybody cares, this is vaguely reminiscent of the pattern used by Ember with reopenClass.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.