Sobes.tech
Middle+

Ce știi despre descriptori?

sobes.tech AI

Răspuns de la AI

Descriptorii în JavaScript sunt obiecte care descriu diferite proprietăți ale unui obiect, cum ar fi valoarea sa (value), posibilitatea de a fi scrisă (writable), posibilitatea de a fi enumerată (enumerable) și posibilitatea de a fi configurată (configurable). Există, de asemenea, descriptorii cu getters și setters.

Există două tipuri de descriptorii:

  • Descriptorii de date: Conțin valoarea proprietății.

    • value: Valoarea proprietății. Poate fi orice tip de date valid.
    • writable: Un boolean. Dacă este true, valoarea proprietății poate fi modificată (obj.prop = newValue). Implicit false pentru proprietățile accessor și true pentru proprietățile de date create prin atribuire obișnuită.
    • enumerable: Un boolean. Dacă este true, proprietatea va fi vizibilă în timpul iterării peste proprietățile obiectului (de exemplu, în bucla for...in sau cu Object.keys()). Implicit false pentru proprietățile adăugate cu Object.defineProperty, și true pentru cele create prin atribuire obișnuită.
    • configurable: Un boolean. Dacă este true, caracteristicile descriptorului (cu excepția value și writable atunci când se schimbă de la date la accessor) pot fi modificate, iar proprietatea poate fi ștearsă. Implicit false pentru proprietățile adăugate cu Object.defineProperty (cu excepția value), și true pentru cele create prin atribuire obișnuită. Odată configurat ca non-configurabil, nu poate fi schimbat înapoi. Poți reduce writable de la true la false, dar nu invers pe un getter/setter non-configurabil.
  • Descriptorii accessor: Definirea funcțiilor care vor fi apelate la obținerea (getter) sau setarea (setter) valorii proprietății.

    • get: Funcție apelată la citirea proprietății. Rezultatul acestei funcții devine valoarea proprietății. Nu primește argumente.
    • set: Funcție apelată la scrierea în proprietate. Primește un argument — noua valoare de setat.
    • enumerable: Un boolean (similar cu descriptorii de date).
    • configurable: Un boolean (similar cu descriptorii de date).

Descriptorii nu pot fi combinați: o proprietate are fie value și writable, fie get și set.

Descriptorii sunt folosiți pentru a controla proprietățile obiectului la un nivel mai jos decât atribuirea obișnuită, în special prin metode precum Object.defineProperty(), Object.defineProperties(), Object.getOwnPropertyDescriptor(), Object.getOwnPropertyDescriptors(), Object.create().

Exemplu de creare a unei proprietăți cu descriptor de date:

// Creăm un obiect gol
const obj = {};

// Definim proprietatea 'name' cu un descriptor de date
Object.defineProperty(obj, 'name', {
  value: 'Alice',
  writable: false, // Proprietatea nu poate fi modificată
  enumerable: true, // Proprietatea va fi enumerabilă
  configurable: false // Caracteristicile proprietății nu pot fi modificate, proprietatea nu poate fi șters
});

console.log(obj.name); // Va afișa: Alice

// Încercare de a modifica proprietatea (va fi ignorată în modul strict sau va arunca o eroare)
obj.name = 'Bob';
console.log(obj.name); // Va afișa: Alice

// Încercare de a șterge proprietatea (va fi ignorată sau va arunca o eroare)
delete obj.name;
console.log(obj.name); // Va afișa: Alice

Exemplu de creare a unei proprietăți cu descriptor de accessor:

// Creăm un obiect cu o variabilă privată
const user = {
  _firstName: 'John', // Variabilă privată prin convenție
  _lastName: 'Doe'
};

// Definim proprietatea 'fullName' cu un descriptor de accessor
Object.defineProperty(user, 'fullName', {
  get() {
    // Getter: returnează numele complet
    return `${this._firstName} ${this._lastName}`;
  },
  set(value) {
    // Setter: împarte numele complet în părți și actualizează variabilele private
    const parts = value.split(' ');
    this._firstName = parts[0];
    this._lastName = parts[1];
  },
  enumerable: true, // Proprietatea va fi enumerabilă
  configurable: true // Caracteristicile proprietății pot fi modificate, proprietatea poate fi ștearsă
});

console.log(user.fullName); // Va afișa: John Doe

user.fullName = 'Peter Pan';
console.log(user._firstName); // Va afișa: Peter
console.log(user._lastName); // Va afișa: Pan
console.log(user.fullName); // Va afișa: Peter Pan

Utilizarea descriptorilor permite crearea de proprietăți imuabile, proprietăți cu calcul leneș, proprietăți cu control al accesului (getters/setters) și gestionarea mai flexibilă a comportamentului obiectelor.