Bu boâlim satr ichki tuzilishiga chuqurroq kiradi. Bu bilimlar agar siz emoji, noyob matematik yoki ieroglif belgilar yoki boshqa noyob simvollar bilan ishlashni rejalashtirgan boâlsangiz foydali boâladi.
Biz allaqachon bilamizki, JavaScript satrlari Unicode ga asoslangan: har bir belgi 1-4 baytlik bayt ketma-ketligi bilan ifodalanadi.
JavaScript bizga quyidagi uchta yozuv usulidan biri bilan uning oân oltinchi Unicode kodini belgilash orqali satrga belgi kiritish imkonini beradi:
-
\xXXXX00danFFgacha qiymat bilan ikkita oân oltinchi raqam boâlishi kerak, keyin\xXXUnicode kodiXXboâlgan belgining oâzi.\xXXyozuvi faqat ikkita oân oltinchi raqamni qoâllab-quvvatlagani uchun, u faqat birinchi 256 ta Unicode belgilari uchun ishlatilishi mumkin.Bu birinchi 256 ta belgi lotin alifbosi, asosiy sintaksis belgilarining koâpchiligi va boshqalarni oâz ichiga oladi. Masalan,
"\x7A""z"(UnicodeU+007A) bilan bir xil.alert( "\x7A" ); // z alert( "\xA9" ); // ©, mualliflik huquqi belgisi -
\uXXXXXXXXaniq 4 ta hex raqam boâlishi kerak, qiymati0000danFFFFgacha, keyin\uXXXXUnicode kodiXXXXboâlgan belgi.U+FFFFdan katta Unicode qiymatlariga ega belgilar ham bu yozuv bilan ifodalanishi mumkin, ammo bu holda biz surrogat juft deb ataladigan narsadan foydalanishimiz kerak (biz surrogat juftlar haqida ushbu bobda keyinroq gaplashamiz).alert( "\u00A9" ); // ©, \xA9 bilan bir xil, 4 raqamli hex yozuvdan foydalanib alert( "\u044F" ); // Ñ, kirill alifbosi harfi alert( "\u2191" ); // â, yuqoriga o'q belgisi -
\u{Xâ¦XXXXXX}Xâ¦XXXXXX0dan10FFFFgacha (Unicode tomonidan belgilangan eng yuqori kod nuqtasi) 1 dan 6 baytgacha oân oltinchi qiymat boâlishi kerak. Bu yozuv bizga barcha mavjud Unicode belgilarini osongina ifodalash imkonini beradi.alert( "\u{20331}" ); // 佫, noyob xitoy belgisi (uzun Unicode) alert( "\u{1F60D}" ); // ð, tabassumli yuz belgisi (boshqa uzun Unicode)
Surrogat juftlar
Barcha tez-tez ishlatiladigan belgilar 2 baytli kodlarga ega (4 hex raqam). Koâpgina Yevropa tillaridagi harflar, raqamlar va asosiy birlashtirilgan CJK ideografik toâplamlar (CJK â Xitoy, Yapon va Koreya yozuv tizimlaridan), 2 baytli tasvirga ega.
Dastlab, JavaScript faqat har bir belgi uchun 2 baytga ruxsat beradigan UTF-16 kodlashtirishga asoslangan edi. Ammo 2 bayt faqat 65536 ta kombinatsiyaga ruxsat beradi va bu Unicode ning har bir mumkin boâlgan belgisi uchun etarli emas.
Shuning uchun 2 baytdan koâproq talab qiladigan noyob belgilar âsurrogat juftâ deb ataladigan 2 baytli belgilar jufi bilan kodlanadi.
Yon taâsir sifatida, bunday belgilarning uzunligi 2:
alert( 'ð³'.length ); // 2, MATHEMATICAL SCRIPT CAPITAL X
alert( 'ð'.length ); // 2, FACE WITH TEARS OF JOY
alert( 'ð©·¶'.length ); // 2, noyob xitoy belgisi
Buning sababi surrogat juftlar JavaScript yaratilgan vaqtda mavjud emas edi va shuning uchun til tomonidan toâgâri ishlov berilmaydi!
Yuqoridagi satrlarning har birida biz bitta belgi bor, ammo length xususiyati 2 uzunligini koârsatadi.
Belgini olish ham qiyin boâlishi mumkin, chunki koâpgina til xususiyatlari surrogat juftlarni ikkita belgi sifatida koâradi.
Masalan, bu yerda biz chiqishda ikkita gâalati belgini koârishimiz mumkin:
alert( 'ð³'[0] ); // g'alati belgilarni ko'rsatadi...
alert( 'ð³'[1] ); // ...surrogat juftning qismlari
Surrogat juft qismlari bir-birisiz maânoga ega emas. Shuning uchun yuqoridagi misoldagi alertlar aslida axlatni koârsatadi.
Texnik jihatdan, surrogat juftlar ularning kodlari bilan ham aniqlanadi: agar belgi 0xd800..0xdbff oraligâidagi kodga ega boâlsa, u surrogat juftning birinchi qismidir. Keyingi belgi (ikkinchi qism) 0xdc00..0xdfff oraligâidagi kodga ega boâlishi kerak. Bu oraliqlar standart tomonidan faqat surrogat juftlar uchun ajratilgan.
Shuning uchun String.fromCodePoint va str.codePointAt usullari surrogat juftlar bilan ishlash uchun JavaScript ga qoâshildi.
Ular mohiyatan String.fromCharCode va str.charCodeAt bilan bir xil, ammo ular surrogat juftlarni toâgâri koâradi.
Bu yerda farqni koârish mumkin:
// charCodeAt surrogat juftlardan xabardor emas, shuning uchun u ð³ ning 1-qismi uchun kodlarni beradi:
alert( 'ð³'.charCodeAt(0).toString(16) ); // d835
// codePointAt surrogat juftlardan xabardor
alert( 'ð³'.codePointAt(0).toString(16) ); // 1d4b3, surrogat juftning ikkala qismini o'qiydi
Aytish kerakki, agar biz 1-pozitsiyadan olsak (va bu yerda ancha notoâgâri), ikkalasi ham juftning faqat 2-qismini qaytaradi:
alert( 'ð³'.charCodeAt(1).toString(16) ); // dcb3
alert( 'ð³'.codePointAt(1).toString(16) ); // dcb3
// juftning ma'nosiz 2-yarmi
Tsiklda koârib chiqish imokniyatiga ega maâlumot turlari bobida surrogat juftlar bilan ishlashning koâproq usullarini topasiz. Buning uchun maxsus kutubxonalar ham bor, ammo bu yerda taklif qilish uchun etarlicha mashhur emas.
Biz satrni ixtiyoriy pozitsiyada shunchaki boâla olmaymiz, masalan str.slice(0, 4) ni olib, uni haqiqiy satr deb kutishimiz mumkin, masalan:
alert( 'salom ð'.slice(0, 4) ); // salom [?]
Bu yerda biz chiqishda axlat belgi (tabassum surrogat juftning birinchi yarmi) ni koârishimiz mumkin.
Agar siz surrogat juftlar bilan ishonchli ishlashni niyat qilsangiz, buni yodda tuting. Katta muammo boâlmasligi mumkin, ammo kamida nima sodir boâlayotganini tushunishingiz kerak.
Diakritik belgilar va normalizatsiya
Koâp tillarda uning ustida/ostida belgi bilan asosiy belgidan tashkil topgan belgilar mavjud.
Masalan, a harfi quyidagi belgilar uchun asosiy belgi boâlishi mumkin: à áâäãåÄ.
Eng keng tarqalgan âkompozitâ belgilar Unicode jadvalida oâzlarining kodiga ega. Ammo ularning hammasi emas, chunki juda koâp mumkin boâlgan kombinatsiyalar mavjud.
Ixtiyoriy kompozitsiyalarni qoâllab-quvvatlash uchun Unicode standarti bizga bir nechta Unicode belgilardan foydalanish imkonini beradi: asosiy belgi va undan keyin uni âbezaydiganâ bir yoki koâp âbelgiâ belgilari.
Masalan, agar bizda S dan keyin maxsus âustidagi nuqtaâ belgisi (kod \u0307) boâlsa, u á¹ sifatida koârsatiladi.
alert( 'S\u0307' ); // á¹
Agar bizga harf ustida (yoki ostida) qoâshimcha belgi kerak boâlsa â muammo yoâq, faqat kerakli belgi belgisini qoâshing.
Masalan, agar biz âostidagi nuqtaâ belgisini (kod \u0323) qoâshsak, âustida va ostida nuqtalar bilan Sâ ga ega boâlamiz: Ṩ.
Masalan:
alert( 'S\u0307\u0323' ); // Ṩ
Bu katta moslashuvchanlikni taâminlaydi, ammo qiziqarli muammoni ham: ikkita belgi vizual jihatdan bir xil koârinishi mumkin, ammo turli Unicode kompozitsiyalar bilan ifodalanishi mumkin.
Masalan:
let s1 = 'S\u0307\u0323'; // Ṩ, S + ustidagi nuqta + ostidagi nuqta
let s2 = 'S\u0323\u0307'; // Ṩ, S + ostidagi nuqta + ustidagi nuqta
alert( `s1: ${s1}, s2: ${s2}` );
alert( s1 == s2 ); // false, garchi belgilar bir xil ko'rinsa ham (?!)
Buni hal qilish uchun har bir satrni bitta ânormalâ shaklga keltiradigan âUnicode normalizatsiyaâ algoritmi mavjud.
U str.normalize() tomonidan amalga oshiriladi.
alert( "S\u0307\u0323".normalize() == "S\u0323\u0307".normalize() ); // true
Bizning vaziyatimizda normalize() aslida 3 ta belgi ketma-ketligini bittaga birlashtirishi qiziq: \u1e68 (ikkita nuqta bilan S).
alert( "S\u0307\u0323".normalize().length ); // 1
alert( "S\u0307\u0323".normalize() == "\u1e68" ); // true
Haqiqatda, bu har doim ham shunday emas. Sababi Ṩ belgisi âetarlicha keng tarqalganâ, shuning uchun Unicode yaratuvchilari uni asosiy jadvalga kiritdilar va unga kod berdilar.
Agar siz normalizatsiya qoidalari va variantlari haqida koâproq bilmoqchi boâlsangiz â ular Unicode standartining ilovasida tasvirlangan: Unicode Normalization Forms, ammo koâpgina amaliy maqsadlar uchun ushbu boâlimdagi maâlumotlar etarli.
Izohlar
<code>yorlig'ini ishlating, bir nechta satrlar uchun - ularni<pre>yorlig'i bilan o'rab qo'ying, 10 satrdan ortiq bo'lsa - sandbox (plnkr, jsbin, codepenâ¦)