Co wiesz o deskryptorach?
sobes.tech AI
Odpowiedź od AI
Deskriptorzy w JavaScript to obiekty opisujące różne właściwości właściwości obiektu, takie jak jej wartość (value), możliwość zapisu (writable), możliwość enumeracji (enumerable) i możliwość konfigurowania (configurable). Istnieją również deskriptor z getterami i setterami.
Istnieją dwa typy deskriptorów:
-
Deskriptorzy danych: Zawierają wartość właściwości.
value: Wartość właściwości. Może być dowolnym poprawnym typem danych.writable: Wartość logiczna. Jeślitrue, wartość właściwości może być zmieniona (obj.prop = nowaWartość). Domyślniefalsedla właściwości dostępu itruedla właściwości danych tworzonych zwykłym przypisaniem.enumerable: Wartość logiczna. Jeślitrue, właściwość będzie widoczna podczas iteracji po właściwościach obiektu (np. w pętlifor...inlub przy użyciuObject.keys()). Domyślniefalsedla właściwości dodanych przezObject.definePropertyitruedla właściwości tworzonych zwykłym przypisaniem.configurable: Wartość logiczna. Jeślitrue, cechy deskriptorów (z wyjątkiemvalueiwritableprzy zmianie z danych na dostępowe) mogą być modyfikowane, a sama właściwość może być usunięta. Domyślniefalsedla właściwości dodanych przezObject.defineProperty(z wyjątkiemvalue) itruedla właściwości tworzonych zwykłym przypisaniem. Po skonfigurowaniu jako niekonfigurowalny, nie można tego zmienić z powrotem. Możesz zmniejszyćwritableztruenafalse, ale nie odwrotnie na niekonfigurowalnym getterze/setterze.
-
Deskriptorzy dostępowe: Definiują funkcje wywoływane przy odczycie (getter) lub ustawieniu (setter) wartości właściwości.
get: Funkcja wywoływana przy odczycie właściwości. Wynik tej funkcji staje się wartością właściwości. Nie przyjmuje argumentów.set: Funkcja wywoływana przy zapisie do właściwości. Przyjmuje jeden argument — nową ustawianą wartość.enumerable: Wartość logiczna (podobnie jak w deskriptorach danych).configurable: Wartość logiczna (podobnie jak w deskriptorach danych).
Deskriptorów nie można mieszać: właściwość ma albo value i writable, albo get i set.
Deskriptorzy służą do zarządzania właściwościami obiektu na niższym poziomie niż zwykłe przypisanie, w szczególności przez metody Object.defineProperty(), Object.defineProperties(), Object.getOwnPropertyDescriptor(), Object.getOwnPropertyDescriptors(), Object.create().
Przykład tworzenia właściwości z deskriptorami danych:
// Tworzymy pusty obiekt
const obj = {};
// Definiujemy właściwość 'name' z deskriptorem danych
Object.defineProperty(obj, 'name', {
value: 'Alice',
writable: false, // Właściwość nie może być zmieniona
enumerable: true, // Właściwość będzie widoczna podczas iteracji
configurable: false // Cechy właściwości nie mogą być zmienione, właściwość nie może być usunięta
});
console.log(obj.name); // Wyświetli: Alice
// Próba zmiany właściwości (zostanie zignorowana w trybie ścisłym lub spowoduje błąd)
obj.name = 'Bob';
console.log(obj.name); // Wyświetli: Alice
// Próba usunięcia właściwości (zostanie zignorowana lub spowoduje błąd)
delete obj.name;
console.log(obj.name); // Wyświetli: Alice
Przykład tworzenia właściwości z deskriptorem dostępów:
// Tworzymy obiekt z prywatną zmienną
const user = {
_firstName: 'John', // Zmienna prywatna według konwencji
_lastName: 'Doe'
};
// Definiujemy właściwość 'fullName' z deskriptorem dostępów
Object.defineProperty(user, 'fullName', {
get() {
// Getter: zwraca pełne imię
return `${this._firstName} ${this._lastName}`;
},
set(value) {
// Setter: dzieli pełne imię na części i aktualizuje prywatne zmienne
const parts = value.split(' ');
this._firstName = parts[0];
this._lastName = parts[1];
},
enumerable: true, // Właściwość będzie widoczna podczas iteracji
configurable: true // Cechy właściwości mogą być zmienione, właściwość może być usunięta
});
console.log(user.fullName); // Wyświetli: John Doe
user.fullName = 'Peter Pan';
console.log(user._firstName); // Wyświetli: Peter
console.log(user._lastName); // Wyświetli: Pan
console.log(user.fullName); // Wyświetli: Peter Pan
Użycie deskriptorów pozwala tworzyć właściwości niemutowalne, właściwości z leniwym obliczaniem, właściwości z kontrolą dostępu (getter/setter) i bardziej elastycznie zarządzać zachowaniem obiektów.