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 bypropDesc
. - If there is a property with key
k
, defining changes the property’s attributes so that they matchpropDesc
.
9.4.1 Object.defineProperty(): defining single properties via descriptors
First, let us create a new property via a descriptor:
const car = {};
Object.defineProperty(car, 'color', {
value: 'blue',
writable: true,
enumerable: true,
configurable: true,
});
assert.deepEqual(
car,
{
color: 'blue',
});
Next, we change the kind of a property via a descriptor; we turn a data property into a getter:
const car = {
color: 'blue',
};
let readCount = 0;
Object.defineProperty(car, 'color', {
get() {
readCount++;
return 'red';
},
});
assert.equal(car.color, 'red');
assert.equal(readCount, 1);
Lastly, we change the value of a data property via a descriptor:
const car = {
color: 'blue',
};
// Use the same attributes as assignment:
Object.defineProperty(
car, 'color', {
value: 'green',
writable: true,
enumerable: true,
configurable: true,
});
assert.deepEqual(
car,
{
color: 'green',
});
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()
:
const legoBrick1 = {};
Object.defineProperties(
legoBrick1,
{
kind: {
value: 'Plate 1x3',
writable: true,
enumerable: true,
configurable: true,
},
color: {
value: 'yellow',
writable: true,
enumerable: true,
configurable: true,
},
description: {
get: function () {
return `${this.kind} (${this.color})`;
},
enumerable: true,
configurable: true,
},
});
assert.deepEqual(
legoBrick1,
{
kind: 'Plate 1x3',
color: 'yellow',
get description() {
return `${this.kind} (${this.color})`;
},
});