Object.defineProperty / defineProperties în JavaScript

Obiecte ES5 (toate browserele moderne)

Definește o proprietate cu control total: dacă poate fi modificată, afișată în bucle sau ștearsă, plus get/set.

Sintaxă
Object.defineProperty(obiect, cheie, descriptor)
Object.defineProperties(obiect, { cheie: descriptor, ... })

Ce face Object.defineProperty / defineProperties

Descriptorul poate avea value, writable (se poate schimba), enumerable (apare în Object.keys și bucle), configurable (poate fi ștearsă sau redefinită) sau, în locul lui value, funcțiile get și set.

Spre deosebire de atribuirea obișnuită, valorile care lipsesc din descriptor sunt false. defineProperties definește mai multe proprietăți deodată. Metodele vechi __defineGetter__ și __defineSetter__ sunt învechite; folosește defineProperty sau get/set direct în obiect.

Parametri

Parametru Descriere
obiect Obiectul modificat.
cheie Numele proprietății.
descriptor Obiect cu value, writable, enumerable, configurable, get, set.

Ce returnează

Obiectul primit.

Exemple

Exemplul 1: O proprietate ascunsă și protejată

const utilizator = { nume: "Ana" };
Object.defineProperty(utilizator, "id", { value: 42 });

try {
  utilizator.id = 99;
} catch (e) {
  console.log(e.message);
}
console.log(utilizator.id);
console.log(Object.keys(utilizator));
console.log(JSON.stringify(utilizator));

Rezultat

Cannot assign to read only property 'id' of object '#<Object>'
42
[ 'nume' ]
{"nume":"Ana"}

Exemplul 2: Getter și setter cu validare

const produs = {};
let pret = 0;

Object.defineProperties(produs, {
  pret: {
    get: () => pret,
    set: (valoare) => {
      if (valoare < 0) throw new RangeError("Prețul nu poate fi negativ");
      pret = valoare;
    },
    enumerable: true,
  },
  pretCuTva: { get: () => +(pret * 1.21).toFixed(2), enumerable: true },
});

produs.pret = 100;
console.log(produs.pret, produs.pretCuTva);
try {
  produs.pret = -5;
} catch (e) {
  console.log(e.message);
}

Rezultat

100 121
Prețul nu poate fi negativ

Greșeli frecvente

  • Te aștepți ca proprietatea definită să apară în Object.keys. Fără enumerable: true, este ascunsă.
  • În modul strict (de exemplu în module sau clase), scrierea într-o proprietate cu writable: false aruncă TypeError, nu este ignorată.

Comenzi înrudite

  • Object.getOwnPropertyDescriptor / Descriptors: Returnează descriptorul unei proprietăți: valoarea și atributele writable, enumerable, configurable, get, set.
  • Object.freeze / isFrozen: Îngheață un obiect: nu i se mai pot adăuga, șterge sau modifica proprietățile.
  • Reflect: Funcții pentru operațiile de bază pe obiecte (citire, scriere, ștergere, chei), cu aceleași nume ca în Proxy.