Skip to content
  • Property Descriptors, freeze & seal · JavaScript

Property Descriptors, freeze & seal

LearnViaNotes @learnvianotes· 2 min read

Every property has hidden attributes — writable, enumerable, configurable — that control whether it can change, show up in loops, or be deleted.

Inspecting descriptors

JavaScript
const obj = { visible: 1 };
console.log(Object.getOwnPropertyDescriptor(obj, "visible"));
Object.defineProperty(obj, "secret", { value: 42 });   // attributes default to false!
console.log(Object.getOwnPropertyDescriptor(obj, "secret"));
console.log(obj, Object.keys(obj), obj.secret);
Output
{ value: 1, writable: true, enumerable: true, configurable: true }
{ value: 42, writable: false, enumerable: false, configurable: false }
{ visible: 1 } [ 'visible' ] 42
AttributeWhen false
writableThe value cannot be reassigned (throws in strict mode)
enumerableHidden from for…in, Object.keys, spread and JSON.stringify
configurableCannot be deleted, and its attributes cannot be changed (except writable → false)
get / setAccessor property instead of a data property (no value/writable)
JavaScript
const account = {};
Object.defineProperty(account, "id", { value: "AC-1", enumerable: true });
try {
  account.id = "hacked";
} catch (e) {
  console.log(e.message);
}
try {
  delete account.id;
} catch (e) {
  console.log(e.message);
}
console.log(account.id);
Output
Cannot assign to read only property 'id' of object '#<Object>'
Cannot delete property 'id' of #<Object>
AC-1

preventExtensions, seal, freeze

Add propsDelete propsChange valuesCheck
Object.preventExtensionsNoYesYesObject.isExtensible
Object.sealNoNoYesObject.isSealed
Object.freezeNoNoNoObject.isFrozen
JavaScript
const sealed = Object.seal({ a: 1 });
sealed.a = 2;
try { sealed.b = 3; } catch (e) { console.log("seal:", e.message); }

const frozen = Object.freeze({ a: 1, nested: { b: 1 } });
try { frozen.a = 2; } catch (e) { console.log("freeze:", e.message); }
frozen.nested.b = 99;                 // freeze is SHALLOW
console.log(sealed, frozen, Object.isFrozen(frozen.nested));
Output
seal: Cannot add property b, object is not extensible
freeze: Cannot assign to read only property 'a' of object '#<Object>'
{ a: 2 } { a: 1, nested: { b: 99 } } false

Deep freeze

JavaScript
function deepFreeze(obj) {
  for (const value of Object.values(obj)) {
    if (value && typeof value === "object") deepFreeze(value);
  }
  return Object.freeze(obj);
}
const config = deepFreeze({ db: { host: "localhost", ports: [5432] } });
try {
  config.db.ports.push(1);
} catch (e) {
  console.log(e.message);
}
Output
Cannot add property 1, object is not extensible

What is the difference between Object.freeze and const?

seal vs freeze?

Free for students and teachers

Write notes like this one

Cards for every idea, quizzes and flashcards, read aloud — on the web and your phone.

Something wrong with this note? Open it to report