Symbol

Browser Support

  • Chrome: 38.
  • Edge: 12.
  • Firefox: 36.
  • Safari: 9.

Source

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?

Tak
Nie

Które z tych stwierdzeń opisuje „znane” symbole?

symbole, których często używasz;
Właściwości statyczne obiektu „Symbol”
Unikalne klucze właściwości umożliwiające dostęp do wbudowanych metod JavaScriptu i ich modyfikowanie