Symbole
Do momentu pojawienia się ES6 JavaScript posiadał sześć typów: null, undefined, boolean, string, number i object. Wraz z ES6 język zyskał nowy typ - Symbol.
Symbol może być nazwą pola obiektu, nie można im również nadawać własności - cechy typu string.
Przykład 7.1
let name = Symbol('name');
let obj = {};
obj[name] = 10;
console.log(obj[name]); // -> 10
Symbole nie są jednak zwykłymi napisami. Każdy utworzony symbol ma unikalną wartość a ich tworzenie nie sprawia żadnych problemów - cechy typu object. Po utworzeniu wartość sybmolu jest niemodyfikowalna.
W odróżnieniu od pozostałych typów, wartości typu Symbol nie można automatycznie przekształcić na napis.
Przykład 7.2
let name = Symbol('name');
console.log('My name is ' + name); // -> typeError
console.log('My name is ' + name.toString());
Do czego można wykorzystać symbole?
Załóżmy, że chcemy stworzyć funkcjonalność, która będzie zliczała wszystkie kliknięcia na stronie i zapisywała ich ilość w obiekcie window w polu clicks. Istnieje spora szansa, że kod z biblioteki czy też innego skryptu może również wykorzystywać to pole. Dodanie lub modyfikacja pola wykorzstywanego również przez inny kod może zakłócić lub nawet zepsuć jego działanie.
Przykład 7.3
window.clicks = 0;
let clicks = Symbol('clicks');
window[clicks] = 0;
Dzięki unikalności symboli możemy dodawać pola do istniejących obieków, które nie należą do nas lub mogą być wykorzystywane przez inne skrypty czy biblioteki bez obaw o kolizje nazw.
Dodatkowo pola z nazwami, które są symbolami są pomijane przez większość narzędzi do inspekcji obiektów takie jak pętla for-in, Object.keys() czy Object.getOwnPropertyNames(). Możemy zatem pokusić się o stworzenie prawie-prywatnych pól w klasach.
Przykład 7.4
let privateField = Symbol('private-field');
class Foo {
constructor (value) {
this[privateField] = value;
}
greet () {
return 'This is my private value: ' + this[privateField];
}
}
let foo = new Foo('bar');
console.log(foo.greet()); // -> 'bar'
Jednak pola z kluczami będącymi symbolami nie są pomijane przez wszystkie dostępne narzędzia do inspekcji obiektów. Nowe interfejsy API pozwala na ich pobranie - Object.getOwnPropertySymbols(), Reflect.ownKeys().
Sposoby uzyskania symbolu
metoda
Symbol()- zwraca za każdym razem unikalny symbol,metoda
Symbol.for(string)- zwraca symbol z tzw. rejestru symboli, każde wywołanieSymbol.for('name')zwróci dokładnie ten sam współdzielony symbol dla opisuname,symbole zdefiniowane w standardzie, np.
Symbol.iterator.