UPDATE : Baru-baru ini artikel brilian dari Mozilla muncul. Bacalah jika Anda penasaran.
Seperti yang Anda ketahui, mereka berencana untuk memasukkan tipe primitif Simbol baru dalam ECMAScript 6 (belum lagi beberapa hal gila lainnya). Saya selalu berpikir bahwa :symbol
gagasan di Ruby tidak perlu; kita bisa dengan mudah menggunakan string biasa, seperti yang kita lakukan pada JavaScript. Dan sekarang mereka memutuskan untuk mempersulit hal-hal di JS dengan itu.
Saya tidak mengerti motivasinya. Bisakah seseorang menjelaskan kepada saya apakah kita benar-benar membutuhkan simbol dalam JavaScript?
private
danpublic
mereka memutuskan untuk parit untuk implementasi kelas yang lebih sederhana. Alih-alihthis.x = x
Anda seharusnya melakukanpublic x = x
dan untuk variabel pribadiprivate y = y
. Mereka memutuskan untuk membuang itu untuk implementasi kelas yang jauh lebih minimal. Simbol kemudian akan menjadi solusi yang diperlukan untuk mendapatkan properti pribadi dalam implementasi minimal.Jawaban:
Motivasi asli untuk memperkenalkan simbol ke Javascript adalah untuk mengaktifkan properti pribadi .
Sayangnya, mereka akhirnya diturunkan peringkatnya. Mereka tidak lagi pribadi, karena Anda dapat menemukannya melalui refleksi, misalnya, menggunakan
Object.getOwnPropertySymbols
atau proksi.Mereka sekarang dikenal sebagai simbol unik dan satu-satunya tujuan penggunaannya adalah untuk menghindari bentrokan nama antar properti. Sebagai contoh, ECMAScript sendiri sekarang dapat memperkenalkan kait ekstensi melalui metode tertentu yang dapat Anda letakkan pada objek (misalnya untuk mendefinisikan protokol iterasi mereka) tanpa risiko mereka berbenturan dengan nama pengguna.
Apakah itu cukup kuat, motivasi untuk menambahkan simbol ke bahasa masih bisa diperdebatkan.
sumber
Object.getOwnPropertySymbols
bukan satu-satunya kebocoran; yang lebih sulit adalah kemampuan untuk menggunakan proxy untuk mencegat akses ke properti "pribadi".Simbol tidak menjamin privasi sejati tetapi dapat digunakan untuk memisahkan properti publik dan internal objek. Mari kita ambil contoh di mana kita dapat menggunakan
Symbol
untuk memiliki properti pribadi.Mari kita ambil contoh di mana properti objek tidak pribadi.
Di atas,
Pet
properti kelastype
tidak pribadi. Untuk menjadikannya pribadi, kita harus membuat penutupan. Contoh di bawah ini mengilustrasikan bagaimana kita dapat membuattype
pribadi menggunakan penutupan.Kerugian dari pendekatan di atas: Kami memperkenalkan penutupan ekstra untuk setiap
Pet
instance yang dibuat, yang dapat merusak kinerja.Sekarang kami perkenalkan
Symbol
. Ini dapat membantu kami menjadikan properti pribadi tanpa menggunakan penutupan tambahan yang tidak perlu. Contoh kode di bawah ini:sumber
_
tidak menjamin privasi sebenarnya tetapi dapat digunakan untuk memisahkan properti publik dan internal objek. Dengan kata lain, jawaban sia-sia.Symbols
adalah jenis objek baru dan khusus yang dapat digunakan sebagai nama properti unik dalam objek. MenggunakanSymbol
bukannyastring
memungkinkan modul yang berbeda untuk membuat properti yang tidak saling bertentangan.Symbols
juga dapat dibuat pribadi, sehingga propertinya tidak dapat diakses oleh siapa pun yang belum memiliki akses langsung keSymbol
.Symbols
adalah primitif baru . Sama sepertinumber
,string
, danboolean
primitif,Symbol
memiliki fungsi yang dapat digunakan untuk membuat mereka. Berbeda dengan primitif lainnya,Symbols
tidak memiliki sintaks literal (misalnya bagaimanastring
memiliki''
) - satu-satunya cara untuk membuat mereka adalah denganSymbol
konstruktor dengan cara berikut:Pada kenyataannya,
Symbol
itu hanya cara yang sedikit berbeda untuk melampirkan properti ke objek - Anda dapat dengan mudah memberikan yang dikenalSymbols
sebagai metode standar, sepertiObject.prototype.hasOwnProperty
yang muncul di semua yang mewarisi dariObject
.Berikut adalah beberapa manfaat dari
Symbol
tipe primitif.Symbols
memiliki debuggability bawaanSymbols
dapat diberikan deskripsi, yang sebenarnya hanya digunakan untuk debugging untuk membuat hidup sedikit lebih mudah ketika masuk ke konsol.Symbols
dapat digunakan sebagaiObject
kunciDi sinilah
Symbol
menjadi sangat menarik. Mereka sangat terkait dengan objek.Symbol
dapat ditetapkan sebagai kunci ke objek, artinya Anda dapat menetapkan jumlah unik yang tidak terbatasSymbol
pada objek dan dijamin bahwa ini tidak akan pernah bertentangan denganstring
kunci, atau unik lainnyaSymbols
.Symbols
dapat digunakan sebagai nilai unik.Mari kita asumsikan Anda memiliki perpustakaan logging, yang meliputi beberapa tingkat log seperti
logger.levels.DEBUG
,logger.levels.INFO
,logger.levels.WARN
dan sebagainya. Dalam kode ES5 Anda ingin membuatnyastring
(jadilogger.levels.DEBUG === 'debug'
), ataunumber
s (logger.levels.DEBUG === 10
). Keduanya tidak ideal karena nilai-nilai itu bukan nilai unik, tetapiSymbol
memang! Jadilogger.levels
menjadi:Baca lebih lanjut di artikel hebat ini .
sumber
log.levels = {DEBUG: Symbol('debug')
dan tidak sederhanalog.levels = {DEBUG:'debug'}
. pada akhirnya sama saja. Saya pikir perlu disebutkan bahwa Simbol tidak terlihat ketika beralih pada kunci Object. itu "benda" mereka{}
dan mencapai hasil yang sama (sebagai nilai unik), atau mungkin literal lebih disukai dalam proyek itu, atau Anda dapat mengatakan seseorang harus membaca dokumen terlebih dahulu.) I secara pribadi berpikir itu memberikan keterbacaan yang baik dari makna yang unik dalam kodeSymbol("some message")
menjadi{message:'some message'}
, bisa dibilang objek melakukan lebih baik di sini karena Anda dapat menambahkan beberapa bidang.Posting ini adalah tentang
Symbol()
, disertakan dengan contoh aktual yang dapat saya temukan / buat dan fakta & definisi yang dapat saya temukan.TLDR;
Ini
Symbol()
adalah tipe data, diperkenalkan dengan rilis ECMAScript 6 (ES6).Ada dua fakta aneh tentang Simbol.
tipe data pertama dan hanya tipe data dalam JavaScript yang tidak memiliki literal
variabel apa pun, yang didefinisikan dengan
Symbol()
, mendapat konten unik, tetapi tidak benar - benar pribadi .setiap data memiliki simbolnya sendiri , dan untuk data yang sama simbolnya akan sama . Info selengkapnya di paragraf berikut, kalau tidak itu bukan TLRD; :)
Bagaimana cara menginisialisasi simbol?
1. Untuk mendapatkan pengidentifikasi unik dengan nilai yang dapat diperdebatkan
Anda dapat melakukannya dengan cara ini:
Atau dengan cara ini:
The
"some text here"
String tidak dapat diekstraksi dari simbol, itu hanya keterangan untuk keperluan debugging. Itu tidak mengubah perilaku simbol dengan cara apa pun. Meskipun, Anda bisaconsole.log
melakukannya (yang adil, karena nilainya untuk debugging, agar tidak salah bahwa log dengan beberapa entri log lainnya):2. Untuk mendapatkan simbol untuk beberapa data string
Dalam hal ini nilai simbol sebenarnya diperhitungkan dan dengan cara ini dua simbol mungkin tidak unik.
Sebut saja simbol-simbol itu "simbol tipe kedua". Mereka tidak berpotongan dengan simbol "tipe pertama" (yaitu yang didefinisikan dengan
Symbol(data)
) dengan cara apa pun.Dua paragraf berikutnya hanya menyinggung simbol tipe pertama .
Bagaimana saya mendapat manfaat dari menggunakan Simbol daripada tipe data yang lebih lama?
Pertama mari kita pertimbangkan objek, tipe data standar. Kita dapat mendefinisikan beberapa pasangan nilai kunci di sana dan memiliki akses ke nilai-nilai dengan menentukan kunci.
Bagaimana jika kita memiliki dua orang dengan nama Peter?
Melakukan ini:
tidak masuk akal.
Jadi, tampaknya menjadi masalah dua orang yang sama sekali berbeda memiliki nama yang sama. Mari kita simak yang baru
Symbol()
. Ini seperti seseorang dalam kehidupan nyata - siapa pun itu unik , tetapi nama mereka bisa sama. Mari kita mendefinisikan dua "orang".Sekarang kami memiliki dua orang yang berbeda dengan nama yang sama. Apakah orang kita memang berbeda? Mereka; Anda dapat memeriksa ini:
Apa manfaatnya bagi kami?
Kami dapat membuat dua entri di objek Anda untuk orang yang berbeda dan mereka tidak dapat salah dengan cara apa pun.
Menggunakan inisialisasi ini, sangat mustahil untuk keliru entri untuk orang pertama dan kedua. Memanggil
console.log
mereka akan dengan benar menampilkan nama kedua mereka.Ketika digunakan dalam objek, bagaimana perbedaannya dibandingkan dengan mendefinisikan properti yang tidak dapat dihitung?
Memang, sudah ada cara untuk mendefinisikan properti untuk disembunyikan dari
Object.keys
dan penghitungan. Ini dia:Apa perbedaan yang terjadi di
Symbol()
sana? Perbedaannya adalah Anda masih bisa mendapatkan properti yang didefinisikan denganObject.defineProperty
cara biasa:Dan jika didefinisikan dengan Simbol seperti pada paragraf sebelumnya:
Anda akan memiliki kemampuan untuk menerima nilainya hanya jika mengetahui variabelnya, yaitu
Selain itu, mendefinisikan properti lain di bawah kunci
"apple"
akan membuat objek menjatuhkan yang lebih lama (dan jika hard-coded, itu bisa menimbulkan kesalahan). Jadi, tidak ada lagi apel! Sangat disayangkan. Mengacu pada paragraf sebelumnya, Simbol itu unik dan mendefinisikan kunci yangSymbol()
akan membuatnya unik.Ketik konversi dan pemeriksaan
Tidak seperti tipe data lainnya, tidak mungkin untuk mengkonversi
Symbol()
ke tipe data lain.Dimungkinkan untuk "membuat" simbol berdasarkan tipe data primitif dengan menelepon
Symbol(data)
.Dalam hal memeriksa tipe, tidak ada yang berubah.
sumber
Beginilah cara saya melihatnya. Simbol memberikan 'tingkat privasi tambahan', dengan mencegah kunci / properti objek tidak diekspos melalui beberapa metode populer seperti Object.keys () dan JSON.stringify ().
Meskipun diberi objek per se, properti seperti itu masih dapat diekspos melalui refleksi, proxy, Object.getOwnPropertySymbols () dll., Tidak ada cara alami untuk mengaksesnya melalui beberapa metode langsung, yang kadang-kadang cukup dari perspektif OOP.
sumber
Simbol JS adalah tipe data primitif baru. Mereka adalah token yang berfungsi sebagai ID unik . Simbol dapat dibuat menggunakan
Symbol
konstruktor. Ambil contoh cuplikan ini dari MDN:Seringkali berguna untuk menggunakan simbol sebagai kunci properti objek unik, misalnya:
sumber
Sumber
sumber