4

I cannot find any information about how one defines static data members in JavaScript using the (relatively new) class syntax. Is it even possible? Please see the following example code:

class Foo {
  constructor() {
    this.name = 'Default Name for each Instance';
    // staticData1 = 'Static Data 1'; // syntax error
    let staticData2 = 'Static Data 2'; // undefined outside
  }

  doSthSpecial() {
    console.log('Executing a method from instance "' + this.name + '"');
  }

  static doSthStatic() {
    console.log('Executing a method that does the same for each instance of "Foo"');
  }
}

foo = new Foo();
console.log(foo.name);
foo.doSthSpecial();
Foo.doSthStatic();
// The problematic case:
console.log(Foo.staticData2);
1
  • This is a stage 2 proposition, no? So, it's not standardized. I'm solving for this by using babel.js. Edit: @shaochuancs explains it well. :) Commented Sep 26, 2016 at 14:21

5 Answers 5

4

You can use Foo.staticData2 = 'Static Data 2' to define static data member of class Foo, after Foo itself is defined.

According to ES6, there is no static property inside class definition, only static method.

In ES7, there is a proposal on static field definition, currently it is at stage 2 (https://github.com/tc39/proposal-class-public-fields). Good new is: Babel has supported this proposal (https://babeljs.io/docs/plugins/transform-class-properties/).

Sign up to request clarification or add additional context in comments.

2 Comments

Okay, first point: That's a pitty because it cannot be done in (anonymous) class expressions like return class { /*...*/ } which are pretty nice otherwise. Second point: great, so i am looking forward to future version of the standard.
Actually, if you use Babel to transform ES6/ES7 code, the stage 2 proposal syntax on static field can be used right now.
4

I found a work-around that comes quite close to what is asked. One can use a computed property ("get method") and make it static. Then there is no need for the "()" function/method call syntax and it is available without any instance of the class. May be a little less efficient though. Example:

let Foo = class {
  static get staticData() {
    return 'Static Data';
  }
}

console.log(Foo.staticData);

Comments

3

This works, and it keeps the messy details inside the class.

class cExample
{  
  static init_index() {
     cExample.index = 0;
  }   

  static get_index() {
     return ++cExample.index;
  }   
}

cExample.init_index();

example = new cExample();
console.log(cExample.get_index());  // 1
example = new cExample();
console.log(cExample.get_index());  // 2
example = new cExample();
console.log(cExample.get_index());  // 3

Comments

2

Another workaround that works for me, not the most elegant but at least until ES7 is to locate the static members after the class:

class Field {

  constructor(index) {
    this.index = index;
  }

  getName(name) {
    return this.name;
  }
}

Field.DISPLAY_AS_TEXT = 2001;
Field.DISPLAY_AS_BARCODE = 2002;

Comments

1

You can also initialize statics in the constructor:

class Foo {
  constructor () {
    if (Foo.myStatic === undefined) Foo.myStatic = 'XXX';
    // or if appropriate
    Foo.myStatic = Foo.myStatic || 'XXX';
    // or the ES2020
    Foo.myStatic = Foo.myStatic ?? 'XXX';
  }
}

Comments

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.