Skip to content

Descriptors

Eugene Lazutkin edited this page Jul 19, 2026 · 9 revisions

JavaScript provides a number of functions that work with descriptors:

This module contains a collection of helpers to simplify some common tasks with descriptors.

The sister module aliases.js provides a set of helpers to alias existing properties using utilities from this module.

descriptors.js

Legend for tables
  • API
    • descriptora property descriptor.
    • getter — a function with no arguments that returns a value.
    • setter — a function with one argument that sets a value.
    • initDescriptor — a descriptor that is used to set default values for getters/setters. Defaults to {enumerable: false, configurable: true}, which is available as the defaultDescriptor.
    • target — an object that will receive the descriptor.
    • source — an object that contains the descriptor.
    • force — if truthy, the descriptor will be added even if it already exists in the target.
    • names — an array of names as strings or symbols, a symbol, or a string containing a comma-separated list of names.

The following utilities are available:

Function Return value Description
makeGetter(getter, initDescriptor) descriptor Creates a getter descriptor.
makeSetter(setter, initDescriptor) descriptor Creates a setter descriptor.
makeAccessors(getter, setter, initDescriptor) descriptor Creates a getter and setter descriptor.
addDescriptor(target, names, descriptor, force) target Adds a descriptor to an object.
addDescriptors(target, dict, force) target Adds multiple descriptors to an object.
addAccessor(target, names, getter, setter, force) target Adds an accessor (getter and setter) to an object.
addAccessors(target, dict, force) target Adds multiple accessors to an object.
addGetter(target, names, getter, force) target Adds a getter to an object.
addGetters(target, dict, force) target Adds multiple getters to an object.
addSetter(target, names, setter, force) target Adds a setter to an object.
addSetters(target, dict, force) target Adds multiple setters to an object.
addProtoDescriptor(Class, names, descriptor, force) Class.prototype Adds a descriptor on a class's prototype.
addProtoDescriptors(Class, dict, force) Class.prototype Adds multiple descriptors on a class's prototype.
addProtoAccessor(Class, names, getter, setter, force) Class.prototype Adds an accessor on a class's prototype.
addProtoAccessors(Class, dict, force) Class.prototype Adds multiple accessors on a class's prototype.
addProtoGetter(Class, names, getter, force) Class.prototype Adds a getter on a class's prototype.
addProtoGetters(Class, dict, force) Class.prototype Adds multiple getters on a class's prototype.
addProtoSetter(Class, names, setter, force) Class.prototype Adds a setter on a class's prototype.
addProtoSetters(Class, dict, force) Class.prototype Adds multiple setters on a class's prototype.
copyDescriptors(target, source, names, force) target Copies multiple descriptors from one object to another.

addDescriptors() uses descriptor objects organized as a dictionary. Its keys can be symbols or strings. Strings are treated as comma-separated lists of names.

addGetter() and addSetter() are the singular counterparts of addGetters() and addSetters() — they add a single getter/setter under one or more names (the names argument accepts the same forms as addDescriptor()).

addGetters() and addSetters() are similar to addDescriptors(), but instead of adding descriptors, descriptors are generated from functions using makeGetter()/makeSetter() with default values. addAccessors() follows the same pattern with {get, set} pairs as dictionary values (either member can be omitted), built with makeAccessors().

The addProto* functions are class-prototype-aware sugar for every installer above — addProtoGetter(Foo, 'name', fn) is equivalent to addGetter(Foo.prototype, 'name', fn), and likewise for descriptors, accessors, and setters. Use these when targeting a class's prototype directly.

copyDescriptors() copies descriptors from one object to another (it can be the same object). names can be one of the following:

  • A string containing a comma-separated list of names.
  • A symbol.
  • An array of symbols or strings.
  • An object with keys as symbols or strings denoting a name of a descriptor from the source object. An associated value is a value suitable as the names argument of addDescriptor().

defaultDescriptor is a descriptor that is used to set default values for getters/setters. It is available as an export from this module so it can be modified globally if needed.

Examples

import {addGetters, copyDescriptors} from 'meta-toolkit/descriptors.js';

class Foo {
  constructor() {
    this.value = 0;
  }
  get triple() {
    return this.value * 3;
  }
}

addGetters(Foo.prototype, {
  half() {
    return this.value / 2;
  },
  double() {
    return this.value * 2;
  }
});

class Bar {
  constructor() {
    this.value = 0;
  }
}

copyDescriptors(Bar.prototype, Foo.prototype, 'triple, double');

class Baz {
  constructor() {
    this.value = 0;
  }
}

copyDescriptors(Baz.prototype, Foo.prototype, {
  double: 'x2',
  triple: 'x3'
});

Exports

All functions are exported by their names. There is no default export.

Clone this wiki locally