


Pemahaman mendalam tentang cara menggunakan Symbol dalam pengetahuan JavaScript_Basic
Apakah itu Simbol?
Simbol bukan ikon, dan juga tidak bermaksud imej kecil boleh digunakan dalam kod:
juga bukan sintaks untuk merujuk kepada sesuatu yang lain. Jadi, apa sebenarnya Simbol?
Tujuh jenis data
Apabila JavaScript diseragamkan pada tahun 1997, terdapat 6 jenis data Sehingga kemunculan ES6, pembolehubah dalam program mestilah salah satu daripada 6 jenis data berikut:
. Tidak ditentukan
Batal
Boolean
Nombor
Rentetan
Objek
Setiap jenis data ialah gabungan siri nilai dan bilangan nilai lima jenis data pertama adalah terhad. Jenis Boolean hanya mempunyai dua nilai: benar dan salah Apabila memberikan nilai kepada pembolehubah jenis Boolean, tiada nilai baharu dijana (dua nilai benar dan salah dikongsi). Untuk Nombor dan Rentetan, nilainya lebih banyak. Pernyataan standard ialah terdapat 18,437,736,874,454,810,627 nilai jenis nombor (termasuk NAN). Bilangan jenis String sukar dikira pada asalnya (2144,115,188,075,855,872 ? 1) ÷ 65,535...tetapi mungkin saya silap.
Bilangan nilai objek tidak terhad, dan setiap objek adalah unik Setiap kali halaman web dibuka, satu siri objek dibuat.
Simbol dalam ES6 juga merupakan jenis data, tetapi ia bukan rentetan atau objek, tetapi jenis data baharu: jenis data ketujuh.
Mari kita lihat senario di mana Simbol mungkin berguna.
Soalan yang ditimbulkan oleh nilai Boolean
Kadangkala adalah sangat mudah untuk menyimpan sementara beberapa data kepunyaan objek lain dalam objek lain. Sebagai contoh, katakan anda menulis pustaka JS yang menggunakan peralihan dalam CSS untuk membuat elemen DOM terbang merentasi skrin Anda sudah tahu bahawa anda tidak boleh menggunakan berbilang peralihan pada div yang sama pada masa yang sama, jika tidak, animasi akan menjadi sangat tidak sedap dipandang. . Anda mempunyai cara untuk mengatasinya, tetapi pertama-tama anda perlu mengetahui sama ada div sudah bergerak.
Bagaimana untuk menyelesaikan masalah ini?
Salah satu cara ialah menggunakan API yang disediakan oleh penyemak imbas untuk mengesan sama ada elemen itu berada dalam keadaan animasi, tetapi ia membuang masa Apabila anda menetapkan elemen untuk bergerak, pustaka anda tahu bahawa elemen itu sedang bergerak.
Apa yang anda perlukan sebenarnya ialah mekanisme untuk menjejaki elemen mana yang bergerak, anda boleh menyimpan elemen bergerak dalam tatasusunan, dan setiap kali anda ingin menghidupkan elemen, semak dahulu sama ada elemen itu sudah ada dalam ini dalam senarai.
Ahem, tetapi jika tatasusunan anda sangat besar, walaupun carian linear seperti ini boleh mencipta isu prestasi.
Jadi, perkara yang anda mahu lakukan ialah tetapkan bendera terus pada elemen:
if (element.isMoving) { smoothAnimations(element); } element.isMoving = true; if (element.isMoving) { smoothAnimations(element); } element.isMoving = true;
Ini juga mempunyai beberapa masalah yang berpotensi, dan anda perlu mengakui hakikat bahawa terdapat kod lain yang mungkin juga beroperasi pada elemen ODM ini.
- Dalam kod lain, sifat yang anda buat akan disenaraikan oleh for-in atau Object.keys(); Kaedah yang sama mungkin telah digunakan dalam beberapa pustaka lain (menetapkan atribut yang sama pada elemen), maka ini akan bercanggah dengan kod anda dan menghasilkan keputusan yang tidak dapat diramalkan;
- Sesetengah perpustakaan lain mungkin menggunakan pendekatan yang sama pada masa hadapan, yang juga akan bercanggah dengan kod anda; Jawatankuasa piawaian boleh menambah kaedah asli .isMoving() pada setiap elemen dan kod anda tidak akan berfungsi sama sekali.
- Sudah tentu, untuk tiga soalan terakhir, anda boleh memilih rentetan tidak bermakna yang tiada siapa akan gunakan:
if (element.__$jorendorff_animation_library$PLEASE_DO_NOT_USE_THIS_PROPERTY$isMoving__) { smoothAnimations(element); } element.__$jorendorff_animation_library$PLEASE_DO_NOT_USE_THIS_PROPERTY$isMoving__ = true; if (element.__$jorendorff_animation_library$PLEASE_DO_NOT_USE_THIS_PROPERTY$isMoving__) { smoothAnimations(element); } element.__$jorendorff_animation_library$PLEASE_DO_NOT_USE_THIS_PROPERTY$isMoving__ = true;
Sintaks
// get 1024 Unicode characters of gibberish var isMoving = SecureRandom.generateName(); ... if (element[isMoving]) { smoothAnimations(element); } element[isMoving] = true; // get 1024 Unicode characters of gibberish var isMoving = SecureRandom.generateName(); ... if (element[isMoving]) { smoothAnimations(element); } element[isMoving] = true;
Kenapa susah sangat? Kami hanya menyimpan sedikit bendera.
Gunakan Simbol untuk menyelesaikan masalah
Nilai simbol boleh dibuat secara pengaturcaraan dan digunakan sebagai nama atribut tanpa perlu risau tentang konflik nama atribut.
调用 Symbol() 方法将创建一个新的 Symbol 类型的值,并且该值不与其它任何值相等。
与数字和字符串一样,Symbol 类型的值也可以作为对象的属性名,正是由于它不与任何其它值相等,对应的属性也不会发生冲突:
obj[mySymbol] = "ok!"; // guaranteed not to collide console.log(obj[mySymbol]); // ok! obj[mySymbol] = "ok!"; // guaranteed not to collide console.log(obj[mySymbol]); // ok!
下面是使用 Symbol 来解决上面的问题:
// create a unique symbol var isMoving = Symbol("isMoving"); ... if (element[isMoving]) { smoothAnimations(element); } element[isMoving] = true; // create a unique symbol var isMoving = Symbol("isMoving"); ... if (element[isMoving]) { smoothAnimations(element); } element[isMoving] = true;
上面代码需要注意几点:
- 方法 Symbol("isMoving") 中的 "isMoving" 字符串被称为 Symbol 的描述信息,这对调试非常有帮助。可以通过 console.log(isMoving) 打印出来,或通过 isMoving.toString() 将 isMoving 转换为字符串时,或在一些错误信息中显示出来。
- element[isMoving] 访问的是 symbol-keyed 属性,除了属性名是 Symbol 类型的值之外,与其它属性都一样。
- 和数组一样,symbol-keyed 属性不能通过 . 操作符来访问,必须使用方括号的方式。
- 操作 symbol-keyed 属性也非常方便,通过上面代码我们已经知道如何获取和设置 element[isMoving] 的值,我们还可以这样使用:if (isMoving in element) 或 delete element[isMoving]。
- 另一方面,只有在 isMoving 的作用域范围内才可以使用上述代码,这可以实现弱封装机制:在一个模块内创建一些 Symbol,只有在该模块内部的对象才能使用,而不用担心与其它模块的代码发生冲突。
由于 Symbol 的设计初衷是为了避免冲突,当遍历 JavaScript 对象时,并不会枚举到以 Symbol 作为建的属性,比如,for-in 循环只会遍历到以字符串作为键的属性,Object.keys(obj)和 Object.getOwnPropertyNames(obj) 也一样,但这并不意味着 Symbol 为键的属性是不可枚举的:使用 Object.getOwnPropertySymbols(obj) 这个新方法可以枚举出来,还有 Reflect.ownKeys(obj) 这个新方法可以返回对象中所有字符串和 Symbol 键。(我将在后面的文章中详细介绍 Reflect 这个新特性。)
库和框架的设计者将会发现很多 Symbol 的用途,稍后我们将看到,JavaScript 语言本身也对其有广泛的应用。
Symbol 究竟是什么呢
> typeof Symbol() "symbol" > typeof Symbol() "symbol"
Symbol 是完全不一样的东西。一旦创建后就不可更改,不能对它们设置属性(如果在严格模式下尝试这样做,你将得到一个 TypeError)。它们可以作为属性名,这时它们和字符串的属性名没有什么区别。
另一方面,每个 Symbol 都是独一无二的,不与其它 Symbol 重复(即便是使用相同的 Symbol 描述创建),创建一个 Symbol 就跟创建一个对象一样方便。
ES6 中的 Symbol 与传统语言(如 Lisp 和 Ruby)中的 Symbol 中的类似,但并不是完全照搬到 JavaScript 中。在 Lisp 中,所有标识符都是 Symbol;在 JavaScript 中,标识符和大多数属性仍然是字符串,Symbol 只是提供了一个额外的选择。
值得注意的是:与其它类型不同的是,Symbol 不能自动被转换为字符串,当尝试将一个 Symbol 强制转换为字符串时,将返回一个 TypeError。
> var sym = Symbol("<3"); > "your symbol is " + sym // TypeError: can't convert symbol to string > `your symbol is ${sym}` // TypeError: can't convert symbol to string > var sym = Symbol("<3"); > "your symbol is " + sym // TypeError: can't convert symbol to string > `your symbol is ${sym}` // TypeError: can't convert symbol to string
Paksaan sedemikian harus dielakkan dan String(sym) atau sym.toString() harus digunakan untuk penukaran.
Tiga cara untuk mendapatkan Simbol
- Symbol() mengembalikan Simbol unik setiap kali ia dipanggil.
- Symbol.for(string) mengembalikan Simbol yang sepadan daripada pendaftaran Simbol Tidak seperti kaedah sebelumnya, Simbol dalam pendaftaran Simbol dikongsi. Iaitu, jika anda memanggil Symbol.for("cat") tiga kali, Simbol yang sama akan dikembalikan. Pendaftaran sangat berguna apabila halaman yang berbeza atau modul yang berbeza dari halaman yang sama perlu berkongsi Simbol.
- Symbol.iterator mengembalikan beberapa Simbol yang dipratakrifkan oleh bahasa, setiap satu dengan tujuan khasnya sendiri.
Jika anda masih tidak pasti sama ada Simbol berguna, bahagian seterusnya akan menjadi sangat menarik kerana saya akan menunjukkan kepada anda Simbol dalam tindakan.
Aplikasi Simbol dalam spesifikasi ES6
Kami sudah tahu bahawa kami boleh menggunakan Simbol untuk mengelakkan konflik kod. Apabila memperkenalkan iterator sebelum ini, kami juga menganalisis bahawa untuk (var item myArray) secara dalaman bermula dengan memanggil myArray[Symbol.iterator](Pada masa itu, saya menyebut bahawa kaedah ini boleh digantikan dengan myArray.iterator(), tetapi menggunakan Simbol mempunyai keserasian ke belakang yang lebih baik.
Masih terdapat beberapa tempat di mana Simbol digunakan dalam ES6. (Ciri ini belum lagi dilaksanakan dalam FireFox.)
- Jadikan instanceof extensible. Dalam ES6, contoh objek bagi ungkapan pembina diseragamkan kepada kaedah pembina: pembina[Symbol.hasInstance](objek), yang bermaksud ia boleh diperluaskan.
- Hapuskan konflik antara ciri baharu dan kod lama.
- Sokong jenis padanan rentetan baharu. Dalam ES5, apabila str.match(myObject) dipanggil, ia mula-mula cuba menukar myObject kepada objek RegExp. Dalam ES6, myObject akan disemak terlebih dahulu untuk kaedah myObject[Symbol.match](str), dan kaedah penghuraian rentetan tersuai boleh disediakan di mana-mana sahaja ungkapan biasa berfungsi.
Penggunaan ini masih agak sempit, tetapi sukar untuk melihat kesan ketara ciri baharu ini hanya dengan melihat kod dalam artikel saya. Simbol JavaScript ialah versi __doubleUnderscores yang dipertingkatkan dalam PHP dan Python, dan organisasi standard akan menggunakannya untuk menambah ciri baharu pada bahasa tanpa menjejaskan kod sedia ada.

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas











Python lebih sesuai untuk pemula, dengan lengkung pembelajaran yang lancar dan sintaks ringkas; JavaScript sesuai untuk pembangunan front-end, dengan lengkung pembelajaran yang curam dan sintaks yang fleksibel. 1. Sintaks Python adalah intuitif dan sesuai untuk sains data dan pembangunan back-end. 2. JavaScript adalah fleksibel dan digunakan secara meluas dalam pengaturcaraan depan dan pelayan.

Peralihan dari C/C ke JavaScript memerlukan menyesuaikan diri dengan menaip dinamik, pengumpulan sampah dan pengaturcaraan asynchronous. 1) C/C adalah bahasa yang ditaip secara statik yang memerlukan pengurusan memori manual, manakala JavaScript ditaip secara dinamik dan pengumpulan sampah diproses secara automatik. 2) C/C perlu dikumpulkan ke dalam kod mesin, manakala JavaScript adalah bahasa yang ditafsirkan. 3) JavaScript memperkenalkan konsep seperti penutupan, rantaian prototaip dan janji, yang meningkatkan keupayaan pengaturcaraan fleksibiliti dan asynchronous.

Penggunaan utama JavaScript dalam pembangunan web termasuk interaksi klien, pengesahan bentuk dan komunikasi tak segerak. 1) kemas kini kandungan dinamik dan interaksi pengguna melalui operasi DOM; 2) pengesahan pelanggan dijalankan sebelum pengguna mengemukakan data untuk meningkatkan pengalaman pengguna; 3) Komunikasi yang tidak bersesuaian dengan pelayan dicapai melalui teknologi Ajax.

Aplikasi JavaScript di dunia nyata termasuk pembangunan depan dan back-end. 1) Memaparkan aplikasi front-end dengan membina aplikasi senarai TODO, yang melibatkan operasi DOM dan pemprosesan acara. 2) Membina Restfulapi melalui Node.js dan menyatakan untuk menunjukkan aplikasi back-end.

Memahami bagaimana enjin JavaScript berfungsi secara dalaman adalah penting kepada pemaju kerana ia membantu menulis kod yang lebih cekap dan memahami kesesakan prestasi dan strategi pengoptimuman. 1) aliran kerja enjin termasuk tiga peringkat: parsing, penyusun dan pelaksanaan; 2) Semasa proses pelaksanaan, enjin akan melakukan pengoptimuman dinamik, seperti cache dalam talian dan kelas tersembunyi; 3) Amalan terbaik termasuk mengelakkan pembolehubah global, mengoptimumkan gelung, menggunakan const dan membiarkan, dan mengelakkan penggunaan penutupan yang berlebihan.

Python dan JavaScript mempunyai kelebihan dan kekurangan mereka sendiri dari segi komuniti, perpustakaan dan sumber. 1) Komuniti Python mesra dan sesuai untuk pemula, tetapi sumber pembangunan depan tidak kaya dengan JavaScript. 2) Python berkuasa dalam bidang sains data dan perpustakaan pembelajaran mesin, sementara JavaScript lebih baik dalam perpustakaan pembangunan dan kerangka pembangunan depan. 3) Kedua -duanya mempunyai sumber pembelajaran yang kaya, tetapi Python sesuai untuk memulakan dengan dokumen rasmi, sementara JavaScript lebih baik dengan MDNWebDocs. Pilihan harus berdasarkan keperluan projek dan kepentingan peribadi.

Kedua -dua pilihan Python dan JavaScript dalam persekitaran pembangunan adalah penting. 1) Persekitaran pembangunan Python termasuk Pycharm, Jupyternotebook dan Anaconda, yang sesuai untuk sains data dan prototaip cepat. 2) Persekitaran pembangunan JavaScript termasuk node.js, vscode dan webpack, yang sesuai untuk pembangunan front-end dan back-end. Memilih alat yang betul mengikut keperluan projek dapat meningkatkan kecekapan pembangunan dan kadar kejayaan projek.

C dan C memainkan peranan penting dalam enjin JavaScript, terutamanya digunakan untuk melaksanakan jurubahasa dan penyusun JIT. 1) C digunakan untuk menghuraikan kod sumber JavaScript dan menghasilkan pokok sintaks abstrak. 2) C bertanggungjawab untuk menjana dan melaksanakan bytecode. 3) C melaksanakan pengkompil JIT, mengoptimumkan dan menyusun kod hot-spot semasa runtime, dan dengan ketara meningkatkan kecekapan pelaksanaan JavaScript.
