Pierwotny symbol reprezentuje unikalną wartość, która nigdy nie koliduje z żadną inną wartością, w tym z wartością innych pierwotnych symboli. Dwa prymitywne ciągi znaków złożone z identycznych znaków są traktowane jako identyczne:
String() === String()
> true
String( "My string." ) === String( "My string." );
> true
Jednak żadne 2 symbole utworzone za pomocą funkcji Symbol()
nie mogą być identyczne:
Symbol() === Symbol()
> false
Ta cecha umożliwia używanie symboli jako unikalnych kluczy właściwości w obiekcie, co zapobiega konfliktom z kluczami dodanymi do tego obiektu przez inny kod.
const mySymbol = Symbol( "Desc" );
const myObject = {};
myObject[mySymbol] = "propSymbol";
myObject
> Object { Symbol("Desc"): "propSymbol" }
Istnieją 3 rodzaje symboli:
- Symbole utworzone za pomocą
Symbol()
- Udostępnione symbole, które są ustawiane i pobierane z globalnego rejestru symboli za pomocą funkcji
Symbol.for()
- „Znane symbole” zdefiniowane jako właściwości statyczne obiektu Symbol. Te symbole zawierają wewnętrzne metody, których nie można przypadkowo nadpisać.
Symbol()
przyjmuje opis (lub „nazwa symbolu”) jako opcjonalny argument.
Te opisy to czytelne etykiety służące do debugowania, które nie wpływają na unikalność wyniku. Każde wywołanie funkcji Symbol
zwraca całkowicie unikalny obiekt podstawowy symbolu, nawet jeśli wiele wywołań ma identyczne opisy:
Symbol( "My symbol." ) === Symbol( "My symbol." );
> false
Podobnie jak w przypadku innych prymitywnych typów danych, symbole dziedziczą metody i właściwości po swoim prototypie. Możesz na przykład uzyskać dostęp do opisu jako właściwości dziedziczonej utworzonego symbolu:
let mySymbol = Symbol( "My symbol." );
mySymbol.description
> "My symbol."
Nie możesz jednak utworzyć symbolu za pomocą słowa kluczowego new
:
let mySymbol = new Symbol();
> Uncaught TypeError: Symbol is not a constructor
Symboli nie można zliczać, co oznacza, że właściwości symboliczne są niedostępne, gdy używasz standardowych metod do ich iterowania. Metoda getOwnPropertySymbols()
zapewnia dostęp do właściwości symbolu obiektu.
Symbole wspólne
Metoda Symbol.for()
próbuje wyszukać wszystkie istniejące symbole w globalnym rejestrze symboli w czasie wykonywania programu, używając danego ciągu jako klucza, i zwraca pasujący symbol, jeśli taki zostanie znaleziony. Jeśli nie znajdzie takiego symbolu, utworzy go z podanym kluczem i doda do rejestru globalnego:
let sharedSymbol = Symbol.for( "My key." );
sharedSymbol === Symbol.for( "My key." )
> true
Te klucze nie pokrywają się funkcjonalnie z opisami przypisanymi do prymitywów utworzonych przez autora Symbol
. Aby uzyskać dostęp do symbolu w rejestrze symboli, musisz go najpierw utworzyć za pomocą for()
:
Symbol( "String" ) === Symbol( "String" );
> false
Symbol( "String" ) === Symbol.for( "String" );
> false
Symbol.for( "String" ) === Symbol.for( "String" );
> true
Aby pobrać klucz dowolnego symbolu z rejestru symboli, użyj:Symbol.keyFor()
let mySymbol = Symbol.for( "Key." );
Symbol.keyFor( mySymbol ) ;
> "Key."
„Znane” symbole
Znane symbole to właściwości statyczne obiektu Symbol
, z których każdy jest symbolem. Znane symbole zapewniają unikalne klucze właściwości, które umożliwiają dostęp do wbudowanych metod JavaScriptu i ich modyfikowanie, a także zapobiegają niezamierzonemu zastąpieniu głównego zachowania.
Symbol;
> function Symbol()
asyncIterator: Symbol(Symbol.asyncIterator)
for: function for()
hasInstance: Symbol("Symbol.hasInstance")
isConcatSpreadable: Symbol("Symbol.isConcatSpreadable")
iterator: Symbol(Symbol.iterator)
keyFor: function keyFor()
length: 0
match: Symbol("Symbol.match")
matchAll: Symbol("Symbol.matchAll")
name: "Symbol"
prototype: Object { … }
replace: Symbol("Symbol.replace")
search: Symbol("Symbol.search")
species: Symbol("Symbol.species")
split: Symbol("Symbol.split")
toPrimitive: Symbol("Symbol.toPrimitive")
toStringTag: Symbol("Symbol.toStringTag")
unscopables: Symbol("Symbol.unscopables")
<prototype>: function ()
Ponieważ symbole są funkcją specyficzną dla ES6, te wartości symboliczne są przeznaczone do używania jako „punkty rozszerzeń” przez programistów, którzy modyfikują działanie JavaScriptu bez wprowadzania problemów z wsteczną zgodnością.
Znane wartości symboli są często stylizowane za pomocą prefiksu @@
lub ujęte w nawiasach klamrowych %
, aby odróżnić ich klucze od zmiennych prototypów. Na przykład @@match
(lub %match%
) jest odwołaniem do niezmiennej wartości Symbol.match
, a nie String.prototype.match
.
Sprawdź swoją wiedzę
Czy możesz użyć new
, aby utworzyć symbol?
Które z tych stwierdzeń opisuje „znane” symbole?