ES6 class getters/setters

Benchmark created on


Setup

var global = this;

(function () {
  class PlainField {
    constructor() {
      this.prop = 0;
    }
  }

  class MethodGetSet {
    constructor() {
      this._prop = 0;
    }
    getProp() {
      return this._prop;
    }
    setProp(value) {
      this._prop = value;
    }
  }

  class AccessorProp {
    constructor() {
      this._prop = 0;
    }
    get prop() {
      return this._prop;
    }
    set prop(value) {
      this._prop = value;
    }
  }

  class DefinePropertyAccessor {
    constructor() {
      this._prop = 0;
    }
  }
  Object.defineProperty(DefinePropertyAccessor.prototype, "prop", {
    get: function () {
      return this._prop;
    },
    set: function (val) {
      this._prop = val;
    },
    configurable: true
  });

  class LegacyDefineGetter {
    constructor() {
      this._prop = 0;
    }
  }
  LegacyDefineGetter.prototype.__defineGetter__("prop", function () {
    return this._prop;
  });
  LegacyDefineGetter.prototype.__defineSetter__("prop", function (val) {
    this._prop = val;
  });

  class CombinedMethod {
    constructor() {
      this._prop = 0;
    }
    prop(value) {
      if (value !== void 0) this._prop = value;
      else return this._prop;
    }
  }

  class GenericKeyedGetSet {
    constructor() {
      this._prop = 0;
    }
    get(key) {
      return this[key];
    }
    set(key, value) {
      this[key] = value;
    }
  }

  class AttributesBagAccessor {
    constructor() {
      this.attributes = { prop: 0 };
    }
    get prop() {
      return this.attributes.prop;
    }
    set prop(value) {
      this.attributes.prop = value;
    }
  }

  class DefinePropertyMethods {
    constructor() {
      this._prop = 0;
    }
  }
  Object.defineProperty(DefinePropertyMethods.prototype, "getProp", {
    value: function () {
      return this._prop;
    },
    configurable: true
  });
  Object.defineProperty(DefinePropertyMethods.prototype, "setProp", {
    value: function (val) {
      this._prop = val;
    },
    configurable: true
  });

  class PrivateFieldAccessor {
    #prop = 0;
    get prop() {
      return this.#prop;
    }
    set prop(v) {
      this.#prop = v;
    }
  }

  global.c1 = new PlainField();
  global.c2 = new MethodGetSet();
  global.c3 = new AccessorProp();
  global.c4 = new DefinePropertyAccessor();
  global.c5 = new LegacyDefineGetter();
  global.c6 = new CombinedMethod();
  global.c7 = new GenericKeyedGetSet();
  global.c8 = new AttributesBagAccessor();
  global.c9 = new DefinePropertyMethods();
  global.c10 = new PrivateFieldAccessor();
})();

Test runner

Ready to run.

Testing in
TestOps/sec
Plain public field
++global.c1.prop;
ready
Method getter + method setter
global.c2.setProp(global.c2.getProp() + 1);
ready
ES6 accessor property (get/set syntax)
global.c3.prop = global.c3.prop + 1;
ready
Prototype accessor (Object.defineProperty)
global.c4.prop = global.c4.prop + 1;
ready
Prototype accessor (__defineGetter__/__defineSetter__)
global.c5.prop = global.c5.prop + 1;
ready
Combined getter/setter method
global.c6.prop(global.c6.prop() + 1);
ready
Generic keyed get/set reading/writing instance slots
global.c7.set("_prop", global.c7.get("_prop") + 1);
ready
“Attributes bag” property access via accessor forwarding
++global.c8.prop;
ready
Methods installed via defineProperty
global.c9.setProp(global.c9.getProp() + 1);
ready
Private field accessor
global.c10.prop = global.c10.prop + 1;
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.