Skip to content

sebmarkbage/ecmascript-scoped-constructor-arguments

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 

Repository files navigation

Scoped Constructor Arguments for ECMAScript Classes

The proposed Class Instance Fields leaves one question open: How do you create constant fields with access to constructor arguments?

This is an idea for a syntactical feature that can address this.

Example Syntax

The syntax builds upon the current class instance fields proposal and existing class methods.

It adds an argument list to the class itself which provides a new scope around the class. The scope semantics of the class body itself doesn't change. I.e. methods and fields are not accessible without the this. prefix.

Simple Arguments

class Point2D (inX, inY) {
  x = inX;
  y = inY;
}

Desugars to:

class Point2D {
  constructor(inX, inY) {
    this.x = inX;
    this.y = inY;
  }
}

Captured Arguments

When the constructor arguments are referred to within methods or field initializers, the method itself is not bound. It is still on the prototype. The method refers to a private slot on whatever this happens to be when the method is invoked.

class Point2D (x, y) {
  measure() {
    return Math.sqrt(x * x + y * y);
  }
}

Pseudo-desugaring to private fields:

class Point2D {
  #_desugared_x;
  #_desugared_y;
  constructor(x, y) {
    this.#_desugared_x = x;
    this.#_desugared_y = y;
  }
  measure() {
    return Math.sqrt(
      this.#_desugared_x * this.#_desugared_x +
      this.#_desugared_y * this.#_desugared_y
    );
  }
}

Conflicting Constructors

At least conflicting constructor arguments is a syntax error. Having both forms in the same class might also need to be a syntax error.

class Point2D (x, y) {
  constructor(x, y, z) { // syntax error?

  }
}

Static Methods

Static methods can be interleaved within this scope but they don't have access to the constructor argument.

class Point2D (x, y) {
  static compare(a, b) {
    return x; // syntax error?
  }
}

Extends

When the class extends another one, the parenthesis have to go before the extends since otherwise it would be ambiguos with a function call.

class Point3D (x, y, z) extends Point2D {
  #z = z;
}

Desugars to:

class Point3D extends Point2D {
  #z;
  constructor(...args) {
    super(...args);
    this.#z = args[2];
  }
}

Status of this Proposal

This might be proposed to ECMAScript in the future but is not yet a concrete proposal. It at least shows a plausible route forward for solving this problem after field initializers.

About

An idea for ECMAScript.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published