Ten post dotyczy Symbol()
dostarczonych rzeczywistych przykładów, które mogłem znaleźć / stworzyć, oraz faktów i definicji, które mogłem znaleźć.
TLDR;
Jest Symbol()
to typ danych wprowadzony wraz z wydaniem ECMAScript 6 (ES6).
Istnieją dwa ciekawe fakty na temat Symbolu.
pierwszy typ danych i jedyny typ danych w JavaScript, który nie ma literału
każda zmienna zdefiniowana za pomocą Symbol()
otrzymuje unikalną treść, ale nie jest tak naprawdę prywatna .
wszelkie dane mają swój własny Symbol, a dla tych samych danych Symbole byłyby takie same . Więcej informacji w następnym akapicie, w przeciwnym razie nie jest to TLRD; :)
Jak zainicjować symbol?
1. Aby uzyskać unikalny identyfikator z wartością do debugowania
Możesz to zrobić w ten sposób:
var mySymbol1 = Symbol();
Lub w ten sposób:
var mySymbol2 = Symbol("some text here");
"some text here"
Ciąg nie mogą być pozyskiwane z symbolem, to tylko opis dla celów debugowania. Nie zmienia to w żaden sposób zachowania symbolu. Chociaż możesz to console.log
zrobić (co jest sprawiedliwe, ponieważ wartość służy do debugowania, aby nie pomylić tego dziennika z innym wpisem):
console.log(mySymbol2);
// Symbol(some text here)
2. Aby uzyskać symbol dla niektórych danych łańcuchowych
W tym przypadku wartość symbolu jest faktycznie brana pod uwagę i w ten sposób dwa symbole mogą nie być unikalne.
var a1 = Symbol.for("test");
var a2 = Symbol.for("test");
console.log(a1 == a2); //true!
Nazwijmy te symbole symbolami „drugiego rodzaju”. Nie przecinają się z symbolami „pierwszego typu” (tj. Tymi, które są zdefiniowane za pomocąSymbol(data)
w żaden sposób z ).
Następne dwa akapity dotyczą tylko pierwszego typu symbolu.
Jak korzystać z Symbol zamiast starszych typów danych?
Rozważmy najpierw obiekt, standardowy typ danych. Możemy zdefiniować tam kilka par klucz-wartość i uzyskać dostęp do tych wartości, określając klucz.
var persons = {"peter":"pan","jon":"doe"};
console.log(persons.peter);
// pan
Co jeśli mamy dwie osoby o imieniu Piotr?
Robiąc to:
var persons = {"peter":"first", "peter":"pan"};
nie miałoby sensu.
Wydaje się więc, że jest to problem dwóch absolutnie różnych osób o tym samym nazwisku. Odwołajmy się zatem do nowych Symbol()
. To jak osoba w prawdziwym życiu - każda osoba jest wyjątkowa , ale jej nazwiska mogą być równe. Zdefiniujmy dwie „osoby”.
var a = Symbol("peter");
var b = Symbol("peter");
Teraz mamy dwie różne osoby o tym samym nazwisku. Czy nasze osoby są naprawdę różne? Oni są; możesz to sprawdzić:
console.log(a == b);
// false
Jak na tym skorzystamy?
Możemy dokonać dwóch wpisów w Twoim obiekcie dla różnych osób i nie można ich w żaden sposób pomylić.
var firstPerson = Symbol("peter");
var secondPerson = Symbol("peter");
var persons = {[firstPerson]:"first", [secondPerson]:"pan"};
Uwaga:
Warto jednak zauważyć, że strunowanie obiektu JSON.stringify
spowoduje usunięcie wszystkich par zainicjowanych Symbolem jako kluczem.
Wykonanie Object.keys
nie zwróci takich Symbol()->value
par.
Dzięki tej inicjalizacji absolutnie niemożliwe jest pomylenie wpisów dla pierwszej i drugiej osoby. Wołanie console.log
o nie poprawnie wypisze ich drugie imię.
console.log(persons[a]);
// first
console.log(persons[b]);
// pan
W przypadku użycia w obiekcie, czym różni się od definiowania właściwości niepoliczalnej?
Rzeczywiście istniał już sposób zdefiniowania właściwości, przed którą należy ukryć Object.keys
i wyliczenia. Oto on:
var anObject = {};
var fruit = "apple";
Object.defineProperty( anObject, fruit, {
enumerable: false,
value: "green"
});
Jaką różnicę Symbol()
tam przynosi? Różnica polega na tym, że nadal można uzyskać właściwość zdefiniowaną Object.defineProperty
w zwykły sposób:
console.log(anObject[fruit]); //green
console.log(anObject["apple"]); //green
console.log(anObject.apple); //green
A jeśli zdefiniowano za pomocą Symbolu jak w poprzednim akapicie:
fruit = Symbol("apple");
Będziesz mógł otrzymać jego wartość tylko wtedy, gdy znasz jej zmienną, tj
console.log(anObject[fruit]); //green
console.log(anObject["apple"]); //undefined
console.log(anObject.apple); //undefined
Co więcej, zdefiniowanie innej właściwości pod kluczem "apple"
spowoduje, że obiekt porzuci starszą (a jeśli zostanie zakodowany na stałe, może wyrzucić błąd). Nie ma już jabłek! Szkoda. Odnosząc się do poprzedniego akapitu, Symbole są unikalne i definiują klucz, Symbol()
który uczyni go unikalnym.
Konwersja i sprawdzanie typów
W przeciwieństwie do innych typów danych, nie można przekonwertować na Symbol()
inny typ danych.
Możliwe jest „uczynienie” symbolu opartym na prymitywnym typie danych przez wywołanie Symbol(data)
.
Pod względem sprawdzania typu nic się nie zmienia.
function isSymbol ( variable ) {
return typeof someSymbol === "symbol";
}
var a_Symbol = Symbol("hey!");
var totally_Not_A_Symbol = "hey";
console.log(isSymbol(a_Symbol)); //true
console.log(isSymbol(totally_Not_A_Symbol)); //false