A pattern that has come up a few times in my code is the following: an object has a property which defaults to an expression based on its other properties unless it’s explicitly set, in which case it functions like a normal property. Essentially, the expression functions as a default value.
Think of a post slug for example: if none is set, then one should be automatically generated from the title. But if one is explicitly set, then that one should be returned.
The easiest way to implement this is to delete the previously stored getter upon setting a value:
let lea = {
name: "Lea Verou",
get id() {
return this.name.toLowerCase().replace(/\W+/g, "-");
},
set id(v) {
delete this.id;
return this.id = v;
}
}
But that’s not really scalable and requires code duplication if you have multiple occurrences of this pattern. Leveraging Object.defineProperty()
Lea provides us with some reusable code, so that we can eventually simply call this one-liner to achieve the same result:
makeGetterWritable(lea, "id", {enumerable: true});