BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News JavaScript Private Class Fields and Methods: Three New Draft Specifications

JavaScript Private Class Fields and Methods: Three New Draft Specifications

Lire ce contenu en français

Bookmarks

While classes have been available in JavaScript since ES2015, they do not include private fields and methods. These capabilities were scrapped during the initial release due to disagreements within the TC39 committee. Three draft specifications intend to bring these capabilities to JavaScript classes in the near future.

Once these specifications are formally accepted, private fields and methods could be defined using the hash '#' sign. The decision to use the hash sign instead of the more traditional underscore '_' was made to avoid breaking changes in existing libraries, which currently mark private fields that way.

This might sound counter-intuitive, however, despite libraries marking fields or methods as private using the underscore, some developers still reference these fields directly. Turning these into truly private variables could break multiple applications, and therefore slow the adoption of the new specifications.

The problem can be demonstrated by an anecdote from React, a popular JavaScript framework, which had to resort to some rather blunt variable names to deter developers from using them (despite being marked as private) such as '_SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED'.

Each of the three TC39 proposals tackles a different aspect of private fields and methods within classes. However, it should be safe to treat them as a single proposal as they will likely be added to JavaScript at the same time. The proposals are:

Class Field Declaration for JavaScript

It is currently not possible to directly define class fields in JavaScript. Instead, developers define these fields within the constructor.

class Counter { 
  constructor() { 
    this.xValue = 0; 
  } 
}

This proposal adds the ability to define public and private fields directly within the class definition.

class Counter { 
  xValue = 0;
  #yValue = 0;
  constructor() { }
}

Private Methods and Getters/Setters for JavaScript Classes

This proposal tackles the addition of private methods and the use of private getter and setters.

class Counter { 
  get #x() { return #xValue; } 
  set #x(value) { }

  #clicked() { } 
}

Static Class Features

This proposal defines the use of private and public static fields and methods.

class CustomDate { 
  static public() = {} 
  static #private() = {} 
}

It's important to note that overusing private fields and methods can be detrimental to a codebase. Private methods can not be tested using unit-tests and can often be an indication of problems with the Single Responsibility Principle.

Private fields and methods have not officially been accepted into JavaScript, but developers can already use them with Babel. A TypeScript implementation is currently in the works and will be available in a future release.

Rate this Article

Adoption
Style

BT