Skip to content

Instantly share code, notes, and snippets.

@rbuckton
Last active October 7, 2020 01:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rbuckton/88ca42785fa8aa38d9f696afcf8d1dff to your computer and use it in GitHub Desktop.
Save rbuckton/88ca42785fa8aa38d9f696afcf8d1dff to your computer and use it in GitHub Desktop.
Syntax for grouped accessors and auto-accessors to classes and object literals.

Grouped Accessors and Auto-Accessors for ECMAScript classes and Object Literals

This introduces new syntax for grouped accessors and auto-accessors to classes and object literals. A grouped accessor is a single declaration that contains either or both both of the get and set methods for an accessor. An auto-accessor is a simplified variant of a grouped accessor that elides the bodies of the get and set methods and introduces a private backing field used by both the getter and setter.

Syntax - Grouped Accessors

class C {
  x {
    get() { ... } // equivalent to `get x() { ... }`
    set(value) { ... } // equivalent to `set x(value) { ... }`
  }
}

const obj = {
  x {
    get() { ... }
    set() { ... }
  }
};

A grouped accessor is essentially a way to define either or both of the get and set methods of an accessor. This provides the following benefits:

  • The get and set are logically grouped together, which can improve readability.
  • A decorator applied to the group can observe both the get and set methods simultaneously, for example:
    function dec({ get, set }, context) {
      ...
      return { get, set, };
    }
    class C {
      @dec
      x {
        get() { ... }
        set(value) { ... }
      }

The semantics of a grouped accessor are as follows:

  • It is a syntax error if a grouped accessor shares the name of another member with the same placement on the class (i.e. static vs. non-static):
    class C {
      x { get() { ... } }
      set x(value) { ... } // Syntax error
    
      y { get() { ... } }
      y { set(value) { ... } } // Syntax error
    }
  • A grouped accessor can specify either a get, a set, or both in any order.
  • A grouped accessor cannot specify more than one get or set.
  • Otherwise, they are defined on the class in the same way that the individual declarations would have been.

Syntax - Auto-Accessors

class C {
  x { get; set; } = 1;
  y { get; } = 2;
  z { get; #set; } = 3;
  constructor() {
    this.#z = 4;
  }
}

const obj = {
  x { get; set; }: 1,
  y { get; }: 2
}

An auto-accessor is a simplified version of a grouped accessor that allows you to elide the body of the get and set methods, and optionally provide an initializer. An auto-initializer introduces a unique private field on the class which is wrapped by a non-private getter and optional non-private setter. #set entry indicates a private setter of the same name as the public member exists on the object and provides privileged access to set the underlying value.

This provides the following benefits:

  • Introduces accessors that can be overridden in subclasses without excess boilerplate.
  • Provides a replacement for fields that allows you to observe reading and writing the value of the field with decorators.
  • Allows you to perform initialization inline with the declaration, similar to fields.

Future Considerations

Accessor/Method Shorthand

Another area of investigation is in the possibility of introducing accessor and method shorthand definitions, similar to arrow functions:

class C extends Base {
  #x = 1;
 
  // constructors
  constructor(x) => super(x, 2)
 
  // methods
  m() => this.#x++;
  
  // accessors
  get x() => this.#x;
  set x(value) => this.#x = value;
  
  // grouped accessors
  y {
    get() => this.#x;
    set(value) => this.#x = value;
  }
}

Grouped Accesor destructuring

const { x { get: get_x } } = obj;
typeof get_x; // "function"

Prior Art

  • C# (1, 2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment