Funcția Object.create - Configurarea proprietților obiectelor.
Funcția Object.create
Un alt mod de a crea un obiect este furnizat de funcția Object.create, care primește doi parametri. Primul parametru este prototipul pe baza căruia va fi creat obiectul, iar al doilea parametru este o definiție a proprietăților și metodelor obiectului:
const tom = Object.create(prototip, { proprietăți și metode });
De exemplu:
const tom = Object.create(Object.prototype, {
name: {
value: "Tom"
},
age: {
value: 39
},
print: {
value: function() { console.log(‘Name: ${this.name} Age: ${this.age}’);
}
}});
console.log(tom.name); // Tom
console.log(tom.age); // 39
tom.print(); // Name: Tom Age: 39
Aici, ca prototip pentru funcția Object.create(), este transmis prototipul lui Object - Object.prototype. Al doilea parametru al funcției este o definiție a proprietăților sub forma:
nume_proprietate/metodă: {
value: valoare_proprietate/metodă
}
Numele proprietății/metodei este asociat unui obiect în care există proprietatea value - aceasta este proprietatea în sine și stochează valoarea proprietății/metodei. De exemplu, proprietatea age este egală cu 39:
age: {
value: 39
}
Pentru metoda, valoarea este definită ca o definiție a funcției.
După crearea obiectului, putem accesa proprietățile și metodele sale, la fel cum am face în orice alt caz:
console.log(tom.age); // 39
Acest mod de creare a obiectelor poate părea prea detaliat și redundant. Cu toate acestea, permite configurarea mai detaliată a proprietăților. Astfel, în afară de câmpul value în configurarea proprietății, putem seta câmpuri suplimentare:
- writeable: stochează o valoare booleană care indică dacă această proprietate este disponibilă pentru scriere, adică dacă îi poate fi atribuită o valoare nouă. Implicit, acest atribut are valoarea false
- enumerable: stochează o valoare booleană care indică dacă proprietatea corespunzătoare este enumerabilă, adică dacă este inclusă atunci când sunt enumerate proprietățile obiectului corespunzător (de exemplu, cu ajutorul unui ciclu for...in). Implicit, are valoarea false.
- configurable: stochează o valoare booleană care indică dacă se poate schimba însuși atributul pentru proprietatea corespunzătoare, adică dacă se poate configura ulterior proprietatea cu ajutorul atributelor. Valoarea implicită pentru acest atribut este, de asemenea, false
- set: definește funcția care este apelată atunci când se schimbă valoarea proprietății
- get: definește funcția care este apelată atunci când se citește valoarea proprietății
Vom aplica câteva dintre aceste atribute:
const tom = Object.create(Object.prototype, {
name: {
value: "Tom",
enumerable: true, // disponibil pentru enumerare
writable: false // NEDisponibil pentru scriere
},
age: {
value: 39,
enumerable: true, // disponibil pentru enumerare
writable: true // disponibil pentru scriere
},
print: {
value: function() { console.log(`Name: ${this.name} Age: ${this.age}`);},
enumerable: false, // NEDisponibil pentru enumerare
writable: false // NEDisponibil pentru scriere
}
});
console.log(tom.name); // Tom
tom.name = "Tomas";
console.log(tom.name); // Tom - proprietatea name nu este disponibilă pentru modificare
console.log(tom.age); // 39
tom.age = 22;
console.log(tom.age); // 22 - proprietatea age este disponibilă pentru modificare
tom.print(); // Name: Tom Age: 22
// enumerarea obiectului
for(prop in tom){
console.log(prop);
}
// Consola afișează:
// name
// age
În exemplul de mai sus, funcția Object.create utilizează mult cod pentru a crea un obiect. Dar ce se întâmplă dacă avem o mulțime de proprietăți și metode, dar avem nevoie doar de o anumită configurație (de exemplu, să facem o proprietate disponibilă doar pentru citire) pentru o singură proprietate?
În acest caz, putem crea obiectul în mod obișnuit și să definim toate proprietățile suplimentare care necesită configurație cu ajutorul funcției Object.defineProperty:
const tom = {
age: 39,
print: function() { console.log(`Name: ${this.name} Age: ${this.age}`); }
};
Object.defineProperty(tom, "name", {
value: "Tom",
writable: false // Nu este disponibil pentru scriere
});
console.log(tom.name); // Tom
tom.name = "Tomas";
console.log(tom.name); // Tom - Proprietatea name nu este disponibilă pentru modificare
tom.print(); // Name: Tom Age: 22
Funcția Object.defineProperty() primește trei parametri. Primul parametru este obiectul pentru care se definește proprietatea. Al doilea parametru este numele proprietății. Al treilea parametru este obiectul de configurare. În acest caz, adăugăm proprietatea name la obiectul tom, care va fi disponibilă doar pentru citire.
Dacă trebuie să definim astfel mai multe proprietăți, atunci se utilizează funcția Object.defineProperties, care primește un obiect și un set de configurări pentru proprietățile adăugate:
const tom = { age: 39 };
// Adăugăm proprietăți la obiectul tom
Object.defineProperties(tom, {
name: { // Definim proprietatea name
value: "Tom",
writable: false // Nu este disponibilă pentru scriere
},
print: { // Definim metoda print
value: function() { console.log(`Nume: ${this.name} Vârstă: ${this.age}`); },
writable: false, // Nu este disponibilă pentru scriere
}
});
tom.name = "Tomas"; // Proprietatea name nu este disponibilă pentru modificare
tom.print = function(){console.log("Salutare Lume");} // Metoda print nu este disponibilă pentru modificare
tom.print(); // Nume: Tom Vârstă: 39
Este important de menționat că astfel putem nu doar adăuga noi proprietăți, ci și să reconfigurăm deja pe cele existente. De exemplu:
const tom = { name: "Tom" };
// Pentru proprietatea name interzicem modificarea
Object.defineProperty(tom, "name", { writable: false });
tom.name = "Tomas";
console.log(tom.name); // Tom - valoarea proprietății nu s-a schimbat