Skip to content

Commit ed61a33

Browse files
add: latest changes into 1-js/99-js-misc unicode and weakref finalization registry topics
1 parent bf1fa48 commit ed61a33

24 files changed

+1969
-9
lines changed
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
# Unicode, Satr ichki tuzilishi
2+
3+
```warn header="Ilg'or bilim"
4+
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.
5+
```
6+
7+
Biz allaqachon bilamizki, JavaScript satrlari [Unicode](https://en.wikipedia.org/wiki/Unicode) ga asoslangan: har bir belgi 1-4 baytlik bayt ketma-ketligi bilan ifodalanadi.
8+
9+
JavaScript bizga quyidagi uchta yozuv usulidan biri bilan uning o'n oltinchi Unicode kodini belgilash orqali satrga belgi kiritish imkonini beradi:
10+
11+
- `\xXX`
12+
13+
`XX` `00` dan `FF` gacha qiymat bilan ikkita o'n oltinchi raqam bo'lishi kerak, keyin `\xXX` Unicode kodi `XX` bo'lgan belgining o'zi.
14+
15+
`\xXX` yozuvi faqat ikkita o'n oltinchi raqamni qo'llab-quvvatlagani uchun, u faqat birinchi 256 ta Unicode belgilari uchun ishlatilishi mumkin.
16+
17+
Bu birinchi 256 ta belgi lotin alifbosi, asosiy sintaksis belgilarining ko'pchiligi va boshqalarni o'z ichiga oladi. Masalan, `"\x7A"` `"z"` (Unicode `U+007A`) bilan bir xil.
18+
19+
```js run
20+
alert( "\x7A" ); // z
21+
alert( "\xA9" ); // ©, mualliflik huquqi belgisi
22+
```
23+
24+
- `\uXXXX`
25+
`XXXX` aniq 4 ta hex raqam bo'lishi kerak, qiymati `0000` dan `FFFF` gacha, keyin `\uXXXX` Unicode kodi `XXXX` bo'lgan belgi.
26+
27+
`U+FFFF` dan 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).
28+
29+
```js run
30+
alert( "\u00A9" ); // ©, \xA9 bilan bir xil, 4 raqamli hex yozuvdan foydalanib
31+
alert( "\u044F" ); // я, kirill alifbosi harfi
32+
alert( "\u2191" ); // ↑, yuqoriga o'q belgisi
33+
```
34+
35+
- `\u{X…XXXXXX}`
36+
37+
`XXXXXXX` `0` dan `10FFFF` gacha (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.
38+
39+
```js run
40+
alert( "\u{20331}" ); // 佫, noyob xitoy belgisi (uzun Unicode)
41+
alert( "\u{1F60D}" ); // 😍, tabassumli yuz belgisi (boshqa uzun Unicode)
42+
```
43+
44+
## Surrogat juftlar
45+
46+
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.
47+
48+
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.
49+
50+
Shuning uchun 2 baytdan ko'proq talab qiladigan noyob belgilar "surrogat juft" deb ataladigan 2 baytli belgilar jufi bilan kodlanadi.
51+
52+
Yon ta'sir sifatida, bunday belgilarning uzunligi `2`:
53+
54+
```js run
55+
alert( '𝒳'.length ); // 2, MATHEMATICAL SCRIPT CAPITAL X
56+
alert( '😂'.length ); // 2, FACE WITH TEARS OF JOY
57+
alert( '𩷶'.length ); // 2, noyob xitoy belgisi
58+
```
59+
60+
Buning sababi surrogat juftlar JavaScript yaratilgan vaqtda mavjud emas edi va shuning uchun til tomonidan to'g'ri ishlov berilmaydi!
61+
62+
Yuqoridagi satrlarning har birida biz bitta belgi bor, ammo `length` xususiyati `2` uzunligini ko'rsatadi.
63+
64+
Belgini olish ham qiyin bo'lishi mumkin, chunki ko'pgina til xususiyatlari surrogat juftlarni ikkita belgi sifatida ko'radi.
65+
66+
Masalan, bu yerda biz chiqishda ikkita g'alati belgini ko'rishimiz mumkin:
67+
68+
```js run
69+
alert( '𝒳'[0] ); // g'alati belgilarni ko'rsatadi...
70+
alert( '𝒳'[1] ); // ...surrogat juftning qismlari
71+
```
72+
73+
Surrogat juft qismlari bir-birisiz ma'noga ega emas. Shuning uchun yuqoridagi misoldagi alertlar aslida axlatni ko'rsatadi.
74+
75+
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.
76+
77+
Shuning uchun [String.fromCodePoint](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint) va [str.codePointAt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt) usullari surrogat juftlar bilan ishlash uchun JavaScript ga qo'shildi.
78+
79+
Ular mohiyatan [String.fromCharCode](mdn:js/String/fromCharCode) va [str.charCodeAt](mdn:js/String/charCodeAt) bilan bir xil, ammo ular surrogat juftlarni to'g'ri ko'radi.
80+
81+
Bu yerda farqni ko'rish mumkin:
82+
83+
```js run
84+
// charCodeAt surrogat juftlardan xabardor emas, shuning uchun u 𝒳 ning 1-qismi uchun kodlarni beradi:
85+
86+
alert( '𝒳'.charCodeAt(0).toString(16) ); // d835
87+
88+
// codePointAt surrogat juftlardan xabardor
89+
alert( '𝒳'.codePointAt(0).toString(16) ); // 1d4b3, surrogat juftning ikkala qismini o'qiydi
90+
```
91+
92+
Aytish kerakki, agar biz 1-pozitsiyadan olsak (va bu yerda ancha noto'g'ri), ikkalasi ham juftning faqat 2-qismini qaytaradi:
93+
94+
```js run
95+
alert( '𝒳'.charCodeAt(1).toString(16) ); // dcb3
96+
alert( '𝒳'.codePointAt(1).toString(16) ); // dcb3
97+
// juftning ma'nosiz 2-yarmi
98+
```
99+
100+
<info:iterable> bobida surrogat juftlar bilan ishlashning ko'proq usullarini topasiz. Buning uchun maxsus kutubxonalar ham bor, ammo bu yerda taklif qilish uchun etarlicha mashhur emas.
101+
102+
````warn header="Xulosa: satrlarni ixtiyoriy nuqtada bo'lish xavfli"
103+
Biz satrni ixtiyoriy pozitsiyada shunchaki bo'la olmaymiz, masalan `str.slice(0, 4)` ni olib, uni haqiqiy satr deb kutishimiz mumkin, masalan:
104+
105+
```js run
106+
alert( 'salom 😂'.slice(0, 4) ); // salom [?]
107+
```
108+
109+
Bu yerda biz chiqishda axlat belgi (tabassum surrogat juftning birinchi yarmi) ni ko'rishimiz mumkin.
110+
111+
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.
112+
````
113+
114+
## Diakritik belgilar va normalizatsiya
115+
116+
Ko'p tillarda uning ustida/ostida belgi bilan asosiy belgidan tashkil topgan belgilar mavjud.
117+
118+
Masalan, `a` harfi quyidagi belgilar uchun asosiy belgi bo'lishi mumkin: `àáâäãåā`.
119+
120+
Eng keng tarqalgan "kompozit" belgilar Unicode jadvalida o'zlarining kodiga ega. Ammo ularning hammasi emas, chunki juda ko'p mumkin bo'lgan kombinatsiyalar mavjud.
121+
122+
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.
123+
124+
Masalan, agar bizda `S` dan keyin maxsus "ustidagi nuqta" belgisi (kod `\u0307`) bo'lsa, u Ṡ sifatida ko'rsatiladi.
125+
126+
```js run
127+
alert( 'S\u0307' ); // Ṡ
128+
```
129+
130+
Agar bizga harf ustida (yoki ostida) qo'shimcha belgi kerak bo'lsa -- muammo yo'q, faqat kerakli belgi belgisini qo'shing.
131+
132+
Masalan, agar biz "ostidagi nuqta" belgisini (kod `\u0323`) qo'shsak, "ustida va ostida nuqtalar bilan S" ga ega bo'lamiz: `Ṩ`.
133+
134+
Masalan:
135+
136+
```js run
137+
alert( 'S\u0307\u0323' ); // Ṩ
138+
```
139+
140+
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.
141+
142+
Masalan:
143+
144+
```js run
145+
let s1 = 'S\u0307\u0323'; // Ṩ, S + ustidagi nuqta + ostidagi nuqta
146+
let s2 = 'S\u0323\u0307'; // Ṩ, S + ostidagi nuqta + ustidagi nuqta
147+
148+
alert( `s1: ${s1}, s2: ${s2}` );
149+
150+
alert( s1 == s2 ); // false, garchi belgilar bir xil ko'rinsa ham (?!)
151+
```
152+
153+
Buni hal qilish uchun har bir satrni bitta "normal" shaklga keltiradigan "Unicode normalizatsiya" algoritmi mavjud.
154+
155+
U [str.normalize()](mdn:js/String/normalize) tomonidan amalga oshiriladi.
156+
157+
```js run
158+
alert( "S\u0307\u0323".normalize() == "S\u0323\u0307".normalize() ); // true
159+
```
160+
161+
Bizning vaziyatimizda `normalize()` aslida 3 ta belgi ketma-ketligini bittaga birlashtirishi qiziq: `\u1e68` (ikkita nuqta bilan S).
162+
163+
```js run
164+
alert( "S\u0307\u0323".normalize().length ); // 1
165+
166+
alert( "S\u0307\u0323".normalize() == "\u1e68" ); // true
167+
```
168+
169+
Haqiqatda, bu har doim ham shunday emas. Sababi `Ṩ` belgisi "etarlicha keng tarqalgan", shuning uchun Unicode yaratuvchilari uni asosiy jadvalga kiritdilar va unga kod berdilar.
170+
171+
Agar siz normalizatsiya qoidalari va variantlari haqida ko'proq bilmoqchi bo'lsangiz -- ular Unicode standartining ilovasida tasvirlangan: [Unicode Normalization Forms](https://www.unicode.org/reports/tr15/), ammo ko'pgina amaliy maqsadlar uchun ushbu bo'limdagi ma'lumotlar etarli.

0 commit comments

Comments
 (0)