Manipulating an ES6 static class property that is an array I've been trying to find a way to create static properties in ES6 classes and have found a solution with the help of various Stack Overflow answers (namely this one and this one). 

However, I also wanted to take this a step further and make the static property an array that can be updated/added to using a special static method. I've managed to come up with something that works. Here is a complete demonstration using the class Apple and static property possibleColors:



    class Apple
    {
      constructor(args = {})
      {
        this.color = args.color || 'red';
        this.description = args.description || 'An apple.';
      }
      
      static get possibleColors()
      {
        if (!this._possibleColors)
          this._possibleColors = ['red', 'green', 'yellow'];
        return this._possibleColors;
      }

      static set possibleColors(arr)
      {
        if (Array.isArray(arr))
          this._possibleColors = arr;
        else
          console.log("Possible colors must be an array.")
      }

      static addPossibleColor(c)
      {
        if (!this._possibleColors)
          this._possibleColors = this.possibleColors;
        this._possibleColors.push(c);
      }

      get color()
      {
        if (!this._color)
          this._color = '';
        return this._color;
      }

      set color(c)
      {
        if (Apple.possibleColors.includes(c))
          this._color = c;
        else
        {
          console.log(`Color '${c}' is not a valid apple color.`);
          if (!this._color)
            this._color = 'red';
        }
      }
    }




The possibleColors property belongs to the class only and will not be a part of new instances. I've also taken measures to ensure that its value is always an array. It defaults to red, green, &amp; yellow, but you can view/change possible colors using the regular getter/setter: 

Apple.possibleColors = ['color', 'othercolor'] 


You can also add new possible colors like this:

Apple.addPossibleColor('newcolor')


In this example, the whole point of having the possibleColors static property is to have a definitive list of valid colors stored in the main class and prevent any Apple instances from being set to a color not in the array. Of course, I can think of other use cases for this kind of technique.

For example, I'm currently trying to write my own basic component system that uses templates to draw/render each component as HTML on the page. The main class (Component or similar) would have a static property for storing the templates in an array, and you'd choose a template from this array when instantiating a component (or it would choose a default if none specified).

What I'd like to know:


Could this approach cause any problems I haven't foreseen (either in this specific scenario or a more complex one)?
Are there better ways to do anything I've demonstrated here?
Is the way I'm handling static properties overall considered good practice?
Protected states require enforcement..
Why would you use the possible colors and complicated apple color vetting process when there is no requirement in your code to do so?
You are using a static list (array) in an effort to protect the state of the Apple, or associated states that rely on apples being specific colors.
Maintaining trust in object states is important and allows you to make assumptions and reduce the code complexity. It is also one of the most important methods coders have of controlling our arch nemeses.. The Bug!
But a chain is only as strong as its weakest link. Even if you put a big sign above it saying &quot;Don't yank this pitifully weak link!&quot; you can't trust coders, not even yourself, for one day the convenience is too tempting, and while in a rush to meet a dead line you yank that chain.
const myApple = new Apple();  // Needs to be &quot;Reddish&quot; not &quot;red&quot;
myApple._color = &quot;Reddish&quot;;   // Done, so much easier than wrangling the 
                              // possibleColors static and its dificult siblings

And just like that all the work put into protecting the state of your apple is out the window.
Coders are lazy they will not put up with complications if there is an easy way. Coders want performant code and they are not going to use getters and setters when there is direct access. Putting a sign up &quot;Do not use&quot; (_ as the metaphoric sign &quot;private&quot;) does not stop use.
If you want to control the color of the apple you must make it impossible to change it without the vetting process, or it is pointless, and pointless code is bad code.