Descriptors and Freezing

Property Descriptors, Accessors, Freezing and Sealing

Every property has a descriptor: value and writable for data properties or get and set for accessors, plus enumerable (listed by Object.keys() and spread) and configurable (deletable and redefinable). Literals set all flags to true; Object.defineProperty() defaults omitted flags to false. Object.preventExtensions() blocks new properties, seal() also blocks deletion, and freeze() also blocks changes, but only one level deep. Violations fail silently in sloppy code and throw in strict mode. To copy getters and flags too, use Object.defineProperties({}, Object.getOwnPropertyDescriptors(src)).

A read-only id, a hidden accessor and a shallow freezeJavaScript
"use strict";
let cents = 1050;
const account = Object.defineProperties({}, {
  id: { value: "A-1", enumerable: true },       // writable, configurable: false
  balance: { get: () => cents / 100, set: (v) => { cents = Math.round(v * 100); } },
});
account.balance = 12.5;
try { account.id = "B-2"; } catch (e) { console.log(e.message); }
const config = Object.freeze({ port: 80, db: { host: "a" } });
config.db.host = "b";                           // freeze is shallow
console.log(account.balance, Object.keys(account), config.db.host, Object.isSealed(config));
Output
Cannot assign to read only property 'id' of object '#<Object>'
12.5 [ 'id' ] b true