Simbol adalah primitif yang relatif baru dan diperkenalkan dalam ES6. Primitif simbol mewakili nilai unik yang tidak pernah bertabrakan dengan nilai lainnya, termasuk nilai primitif simbol lainnya. Dua primitif string yang terdiri dari karakter identik dievaluasi sebagai benar-benar sama:
String() === String()
> true
String( "My string." ) === String( "My string." );
> true
Namun, tidak ada dua simbol yang dibuat menggunakan fungsi Symbol()
yang bisa sama persis:
Symbol() === Symbol()
> false
Sifat ini memungkinkan Anda menggunakan simbol sebagai kunci properti unik pada suatu objek, sehingga mencegah tumbukan dengan kunci yang mungkin ditambahkan oleh kode lain ke objek tersebut.
const mySymbol = Symbol( "Desc" );
const myObject = {
}
myObject
> Object { Symbol("Desc"): "propSymbol" }
Ada tiga jenis simbol:
- Simbol dibuat dengan
Symbol()
- Simbol bersama yang ditetapkan dan diambil dari registry Simbol global menggunakan
Symbol.for()
- "Simbol terkenal" didefinisikan sebagai properti statis pada objek Simbol. Simbol ini berisi metode internal yang tidak dapat ditimpa secara tidak sengaja.
Symbol()
menerima deskripsi (atau "nama simbol") sebagai argumen opsional.
Deskripsi ini adalah label yang dapat dibaca manusia untuk tujuan proses debug, dan
tidak memengaruhi keunikan hasil. Setiap panggilan ke Symbol
akan menampilkan
primitif simbol yang benar-benar unik, meskipun beberapa panggilan memiliki deskripsi
yang identik:
Symbol( "My symbol." ) === Symbol( "My symbol." );
> false
Seperti jenis data primitif lainnya, simbol mewarisi metode dan properti dari prototipe-nya. Misalnya, Anda dapat mengakses deskripsi sebagai properti turunan dari simbol yang dibuat:
let mySymbol = Symbol( "My symbol." );
mySymbol.description
> "My symbol."
Namun, Anda tidak dapat membuat simbol menggunakan kata kunci new
:
let mySymbol = new Symbol();
> Uncaught TypeError: Symbol is not a constructor
Simbol tidak dapat dihitung, yang berarti properti simbolis tidak tersedia
saat menggunakan metode standar untuk melakukan iterasi pada simbol tersebut. Metode getOwnPropertySymbols()
memberikan akses ke properti simbol objek.
Simbol bersama
Metode Symbol.for()
mencoba mencari simbol yang ada di registry simbol global tingkat runtime dengan string tertentu sebagai kuncinya, dan menampilkan simbol yang cocok jika ditemukan. Jika tidak menemukannya, kode akan membuat simbol
dengan kunci yang ditentukan dan menambahkannya ke registry global:
let sharedSymbol = Symbol.for( "My key." );
sharedSymbol === Symbol.for( "My key." )
> true
Kunci ini tidak memiliki tumpang-tindih fungsional yang sama dengan deskripsi yang ditetapkan ke
primitif Symbol
yang dibuat penulis. Untuk mengakses simbol dalam registry simbol, Anda harus membuatnya terlebih dahulu menggunakan for()
:
Symbol( "String" ) === Symbol( "String" );
> false
Symbol( "String" ) === Symbol().for( "String" );
> false
Symbol().for( "String" ) === Symbol().for( "String" );
> true
Untuk mengambil kunci simbol apa pun dari registry simbol, gunakan Symbol.keyFor()
:
let mySymbol = Symbol.for( "Key." );
Symbol.keyFor( mySymbol ) ;
> "Key."
Simbol "terkenal"
Simbol terkenal adalah properti statis objek Symbol
, yang masing-masing
merupakan simbol itu sendiri. Simbol terkenal menyediakan kunci properti unik untuk
mengakses dan mengubah metode bawaan JavaScript, sekaligus mencegah perilaku inti
ditimpa secara tidak sengaja.
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 ()
Karena simbol adalah fitur khusus untuk ES6, nilai simbolis ini dimaksudkan untuk digunakan sebagai "titik ekstensi" bagi developer yang mengubah perilaku JavaScript tanpa menimbulkan masalah kompatibilitas mundur.
Nilai simbol yang terkenal sering kali diberi gaya dengan
awalan @@
atau digabungkan dalam %
untuk
membedakan kuncinya dari prototipe yang dapat diubah. Misalnya, @@match
(atau %match%
) adalah referensi ke Symbol.match
yang tidak dapat diubah, bukan String.prototype.match
.
Menguji pemahaman Anda
Dapatkah Anda menggunakan new
untuk membuat simbol?
Manakah dari berikut ini yang menggambarkan simbol 'terkenal'?