9.4 Defining properties via descriptors

If we define a property with the key k via a property descriptor propDesc, then what happens depends:

  • If there is no property with key k, a new own property is created that has the attributes specified by propDesc.
  • If there is a property with key k, defining changes the property’s attributes so that they match propDesc.

9.4.1 Object.defineProperty(): defining single properties via descriptors

First, let us create a new property via a descriptor:

  1. const car = {};
  2. Object.defineProperty(car, 'color', {
  3. value: 'blue',
  4. writable: true,
  5. enumerable: true,
  6. configurable: true,
  7. });
  8. assert.deepEqual(
  9. car,
  10. {
  11. color: 'blue',
  12. });

Next, we change the kind of a property via a descriptor; we turn a data property into a getter:

  1. const car = {
  2. color: 'blue',
  3. };
  4. let readCount = 0;
  5. Object.defineProperty(car, 'color', {
  6. get() {
  7. readCount++;
  8. return 'red';
  9. },
  10. });
  11. assert.equal(car.color, 'red');
  12. assert.equal(readCount, 1);

Lastly, we change the value of a data property via a descriptor:

  1. const car = {
  2. color: 'blue',
  3. };
  4. // Use the same attributes as assignment:
  5. Object.defineProperty(
  6. car, 'color', {
  7. value: 'green',
  8. writable: true,
  9. enumerable: true,
  10. configurable: true,
  11. });
  12. assert.deepEqual(
  13. car,
  14. {
  15. color: 'green',
  16. });

We have used the same property attributes as assignment.

9.4.2 Object.defineProperties(): defining multiple properties via descriptors

Object.defineProperties() is the multi-property version of `Object.defineProperty():

  1. const legoBrick1 = {};
  2. Object.defineProperties(
  3. legoBrick1,
  4. {
  5. kind: {
  6. value: 'Plate 1x3',
  7. writable: true,
  8. enumerable: true,
  9. configurable: true,
  10. },
  11. color: {
  12. value: 'yellow',
  13. writable: true,
  14. enumerable: true,
  15. configurable: true,
  16. },
  17. description: {
  18. get: function () {
  19. return `${this.kind} (${this.color})`;
  20. },
  21. enumerable: true,
  22. configurable: true,
  23. },
  24. });
  25. assert.deepEqual(
  26. legoBrick1,
  27. {
  28. kind: 'Plate 1x3',
  29. color: 'yellow',
  30. get description() {
  31. return `${this.kind} (${this.color})`;
  32. },
  33. });