static/class properties

# Dmitry Soshnikov (7 years ago)

Out of curiosity: we have static methods, but seems there is no yet ability to define a class/static property/constant.

class A { const VALUE = 10; }

or (probably better to be consistent with static methods):

class A { static VALUE = 10; }

Was it a special reason or was it just forgotten? (One could define a var in the static scope, but seems it's useful to have the feature inline in the class bodies).

P.S.: in addition -- why not to reuse static for also simple functions?

function getHeavyValue() { static heavyValue; if (!heavyValue) { // heavy calc } return heavyValue; }

Dmitry

# Rick Waldron (7 years ago)

On Thu, Sep 19, 2013 at 4:16 AM, Dmitry Soshnikov < dmitry.soshnikov at gmail.com> wrote:

Hi,

Out of curiosity: we have static methods, but seems there is no yet ability to define a class/static property/constant.

class A { const VALUE = 10; }

or (probably better to be consistent with static methods):

class A { static VALUE = 10; }

There are a few reasons, the first being that there was no "static" prefix when maximally minimal classes were accepted, but of course the class feature grew a little (which is a good thing). "static", with regard to methods, is straight forward, whereas data properties create a potential ambiguity:

class A { const VALUE = 10; }

A decision would have to be made for "const VALUE = 10" here: does it mean mean A.VALUE and not var a = new A(); a.VALUE;? If it means the latter, then there are implications that will change a possible future that includes "private x = 1" in the same class-body position.

I spoke with Allen off-line and he reminded me that a static "const-like" could be created like this:

class A { static get VALUE() { return "some constant value"; } }

A.VALUE;

(I quoted const-like, because this is still configurable)

Was it a special reason or was it just forgotten? (One could define a var in the static scope, but seems it's useful to have the feature inline in the class bodies).

P.S.: in addition -- why not to reuse static for also simple functions?

function getHeavyValue() { static heavyValue; if (!heavyValue) { // heavy calc } return heavyValue; }

This is a no-go because "static" is only reserved in strict mode, which means

function foo() { static = 1; }

(awful, yes—but legal)

# Erik Arvidsson (7 years ago)

On Thu, Sep 19, 2013 at 9:30 AM, Rick Waldron <waldron.rick at gmail.com> wrote:

On Thu, Sep 19, 2013 at 4:16 AM, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> wrote:

Hi,

Out of curiosity: we have static methods, but seems there is no yet ability to define a class/static property/constant.

class A { const VALUE = 10; }

or (probably better to be consistent with static methods):

class A { static VALUE = 10; }

There are a few reasons, the first being that there was no "static" prefix when maximally minimal classes were accepted, but of course the class feature grew a little (which is a good thing). "static", with regard to methods, is straight forward, whereas data properties create a potential ambiguity:

class A { const VALUE = 10; }

A decision would have to be made for "const VALUE = 10" here: does it mean mean A.VALUE and not var a = new A(); a.VALUE;? If it means the latter, then there are implications that will change a possible future that includes "private x = 1" in the same class-body position.

I spoke with Allen off-line and he reminded me that a static "const-like" could be created like this:

class A { static get VALUE() { return "some constant value"; } }

A.VALUE;

(I quoted const-like, because this is still configurable)

Was it a special reason or was it just forgotten? (One could define a var in the static scope, but seems it's useful to have the feature inline in the class bodies).

P.S.: in addition -- why not to reuse static for also simple functions?

function getHeavyValue() { static heavyValue; if (!heavyValue) { // heavy calc } return heavyValue; }

This is a no-go because "static" is only reserved in strict mode, which means

function foo() { static = 1; }

(awful, yes—but legal)

Not true. static is a keyword since ES2.

7.4.3, Future keywords

www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262, 2nd edition, August 1998.pdf

# Erik Arvidsson (7 years ago)

I stand corrected... this was relaxed in ES5 to only be a keyword in strict mode.

# Boris Zbarsky (7 years ago)

On 9/19/13 9:30 AM, Rick Waldron wrote:

class A { const VALUE = 10; }

A decision would have to be made for "const VALUE = 10" here: does it mean mean A.VALUE and not var a = new A(); a.VALUE;?

The current web platform (and hence WebIDL) answer is "both". So both XMLHttpRequest.UNSENT and XMLHttpRequest.prototype.UNSENT exist and have the same value.

# Andrea Giammarchi (7 years ago)

I cannot remember if that has been considered historically a Java or PHP error/ambiguity ... I'd rather not repeat that in ES6.

A Class constant should have nothing to do with instances but instances can have properties that returns that class constant, if needed.

We've got new syntax here so I say this is the easier to read/write/understand ... no need a big chapter explaining what's going on ^_^

class A {
  static A.VALUE = 10;
}

or ...

class A {
  static {
    VALUE = 10;
  }
}

as in redefine.js

Both will desugar in

function A(){}
Object.defineProperty(A, 'VALUE', {value: 10});

leaving the prototype alone with its own different world problems.

My 2 cents

# Rick Waldron (7 years ago)

On Thu, Sep 19, 2013 at 1:14 PM, Andrea Giammarchi < andrea.giammarchi at gmail.com> wrote:

I cannot remember if that has been considered historically a Java or PHP error/ambiguity ... I'd rather not repeat that in ES6.

A Class constant should have nothing to do with instances but instances can have properties that returns that class constant, if needed.

We've got new syntax here so I say this is the easier to read/write/understand ... no need a big chapter explaining what's going on ^_^

class A {
  static A.VALUE = 10;
}

But this doesn't match the existing:

class A { static foo() { return "Returned from a class-side method"; } }

Means: A.foo()

And it's still possible to add:

class A { static VALUE = 10; }

Sometime in the future

or ...

class A {
  static {
    VALUE = 10;
  }
}

This is nice but conflicts with the existing "static" MethodDefinition form

# Andrea Giammarchi (7 years ago)

the A.whatever is explicit to the class so it's the less ambiguous, IMO

I see already confusing to understand if properties will be defined in the instance or in the class ... could not tell easily while I could, reading A.VALUE = 10; instead.

Anyway, using that outside the class definition as:

class A {
  // do whatever in here ...
  // that you want inherited/assigned too
}
const A.VALUE = 10;

is already good, if possible, and ambiguity free (but I cannot remember the const obj.prop = value; state)

Hopefully in that way instances won't inherit a thing for sure ^_^

# Andrea Giammarchi (7 years ago)

Just some thought about the natiral following option:

class A {}

const A.{
  VALUE = 10;
  METHOD = function () {};
  THOUGHTS = '?';
}
# Dmitry Soshnikov (7 years ago)

On Sep 19, 2013, at 6:30 AM, Rick Waldron wrote:

On Thu, Sep 19, 2013 at 4:16 AM, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> wrote: Hi,

Out of curiosity: we have static methods, but seems there is no yet ability to define a class/static property/constant.

class A { const VALUE = 10; }

or (probably better to be consistent with static methods):

class A { static VALUE = 10; }

A decision would have to be made for "const VALUE = 10" here: does it mean mean A.VALUE and not var a = new A(); a.VALUE;?

Yes, it's true, that if a property is placed in the prototype, it can be treated sort of a "static", i.e. shared between all instances. However, I'd assume static foo = 10; means the same as static foo() {}, that is -- placed on the class object itself.

If it means the latter, then there are implications that will change a possible future that includes "private x = 1" in the same class-body position.

In contrast, "private" modifier should declare a property per instance of course.

I spoke with Allen off-line and he reminded me that a static "const-like" could be created like this:

class A { static get VALUE() { return "some constant value"; } }

Yeah, but this is "too unsugared" for simple class consts. For accessor consts still work though.

So, if it's not that hard to add to the spec, I'd argue for:

class A { static foo = 10; // or const foo = 10; whatever }

desugars to:

A.foo = 10;

function getHeavyValue() { static heavyValue; if (!heavyValue) { // heavy calc } return heavyValue; }

This is a no-go because "static" is only reserved in strict mode, which means

function foo() { static = 1; }

OK.

Dmitry

# Andrew Fedoniouk (7 years ago)

On Thu, Sep 19, 2013 at 11:08 AM, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote:

the A.whatever is explicit to the class so it's the less ambiguous, IMO

I see already confusing to understand if properties will be defined in the instance or in the class ... could not tell easily while I could, reading A.VALUE = 10; instead.

Anyway, using that outside the class definition as:

class A {
  // do whatever in here ...
  // that you want inherited/assigned too
}
const A.VALUE = 10;

is already good, if possible, and ambiguity free (but I cannot remember the const obj.prop = value; state)

Hopefully in that way instances won't inherit a thing for sure ^_^

I did them this way:

class Foo {

this var instanceVar1 = 1; this var instanceVar2 = 2;

var classVar1 = 3; var classVar2 = 3; }

'this var' can easily be parsed and will not break existing grammar.

In fact I do have [1] other "this thing" combinations:

"this function" - reference of current function inside the function. Useful e.g. for recursive calls of anonymous functions. "this super" - reference of 'this' of outer function. "this super super ..." - the same as above but for outer this of outer, etc.

[1] www.codeproject.com/Articles/33662/TIScript

# Dmitry Soshnikov (7 years ago)

On Thu, Sep 19, 2013 at 9:20 PM, Dmitry Soshnikov < dmitry.soshnikov at gmail.com> wrote:

On Sep 19, 2013, at 6:30 AM, Rick Waldron wrote:

On Thu, Sep 19, 2013 at 4:16 AM, Dmitry Soshnikov < dmitry.soshnikov at gmail.com> wrote:

Hi,

Out of curiosity: we have static methods, but seems there is no yet ability to define a class/static property/constant.

class A { const VALUE = 10; }

or (probably better to be consistent with static methods):

class A { static VALUE = 10; }

A decision would have to be made for "const VALUE = 10" here: does it mean mean A.VALUE and not var a = new A(); a.VALUE;?

Yes, it's true, that if a property is placed in the prototype, it can be treated sort of a "static", i.e. shared between all instances. However, I'd assume static foo = 10; means the same as static foo() {}, that is -- placed on the class object itself.

If it means the latter, then there are implications that will change a possible future that includes "private x = 1" in the same class-body position.

In contrast, "private" modifier should declare a property per instance of course.

I spoke with Allen off-line and he reminded me that a static "const-like" could be created like this:

class A { static get VALUE() { return "some constant value"; } }

Yeah, but this is "too unsugared" for simple class consts. For accessor consts still work though.

So, if it's not that hard to add to the spec, I'd argue for:

class A { static foo = 10; // or const foo = 10; whatever }

desugars to:

A.foo = 10;

Sorry for "beating a dead horse" (actually, I don't think it's what I'm doing), but this topic was left uncleared, so just wanted to double-check the status, and possibility of nevertheless including this still in ES6:

Locally, using ES6 classes transform already for a while, we periodically receive questions from devs like: "OK, we got static methods, cool, but how do I define a static class const?"

There is no good answer yet, and referring them to ES7 era doesn't sound to me as a good solution for every-day practical programming, when people need these constants.

I know there were some discussions and bikeshedding around it, like: 1) whether it should go to the constructor (of course it should!), or 2) to the prototype, or 3) even to an instance (that doesn't make much sense, etc. But the basic form, that is used in other languages, and that is widely used as an everyday practical pattern, could be easily added to the ES6 spec:

var request = new Request;

if (request.status == Request.Connected) {
  ...
}

Where should we propose devs to define these consts that should be used at call-sites? In nowadays practice, the namespace for them is a class object. For now, they don't have other option than define them manually afterwards:

class Request {
  ...
}

Request.Initialized = 0;
Request.Connected = 1;
...

Potentially can be batch in to one call to Object.mixin, but the question is: we got sugared classes now, why this desugared imperative class constants definitions?

(the other option is to have a getter as was mentioned above, but this is IMO to heavyweight for a simple constant)

Anyways, I just want to make sure, we don't make a design lack/mistake here not providing this ability (and again, it's based not on simple design thoughts (that are also true), but on actual practical questions from programmers who already use ES6 classes).

From this perspective, I'd still would ask for inclusion of this sugar:

class Request {
  const Connected = 1;
  ...
}

Into:

function Request() {}
Request.Connected = 1;

P.S. In this particular case, one could define two entities: the Request class, and the RequestStatus object for storing the constants, but in general case, classes still should have ability to serve as namespaces for consts.

Dmitry