Bawiłem się z JS i nie mogę zrozumieć, w jaki sposób JS decyduje, które elementy dodać do utworzonej tablicy podczas używania Array.from()
. Na przykład następujący emoji 👍 ma wartość length
2, ponieważ składa się z dwóch punktów kodowych, ale Array.from()
traktuje te dwa punkty kodowe jako jeden, dając tablicę z jednym elementem:
const emoji = '👍';
console.log(Array.from(emoji)); // Output: ["👍"]
Jednak niektóre inne znaki mają również dwa punkty kodowe, takie jak ten znak षि
(również ma .length
2). Jednak Array.from
nie „grupuje” tej postaci i zamiast tego wytwarza dwa elementy:
const str = 'षि';
console.log(Array.from(str)); // Output: ["ष", "ि"]
Moje pytanie brzmi: co decyduje o tym, czy znak jest podzielony (jak w przykładzie 2), czy traktowany jako jeden pojedynczy element (jak w przykładzie jeden), gdy znak składa się z dwóch punktów kodowych?
javascript
string
unicode
iterator
Shnick
źródło
źródło
षि
jest 2 oddzielnymi postaciamilength
. Iteratory, a nawetSet
nie działają z tymOdpowiedzi:
Array.from
Najpierw próbuje wywołać iterator argumentu, jeśli ma jeden, a łańcuchy mają iteratory, więc wywołujeString.prototype[Symbol.iterator]
, więc sprawdźmy, jak działa metoda prototypowa. Jest to opisane w specyfikacji tutaj :Wyszukiwanie w
CreateStringIterator
końcu prowadzi do tego21.1.5.2.1 %StringIteratorPrototype%.next ( )
, co:To,
CodeUnitCount
co Cię interesuje. Numer ten pochodzi z CodePointAt :Tak więc, podczas iteracji po ciągu z
Array.from
, zwraca CodeUnitCount 2 tylko wtedy, gdy dany znak jest początkiem pary zastępczej. Znaki interpretowane jako pary zastępcze opisano tutaj :षि
nie jest parą zastępczą:Ale
👍
bohaterami są:Pierwszym kodem znakowym
'👍'
jest szesnastkowy kod D83D, który należy do0xD800 to 0xDBFF
wiodących zastępców. W przeciwieństwie do tego, pierwszy kod znakowy'षि'
jest znacznie niższy i nie jest. Więc'षि'
dzieli się, ale'👍'
nie robi.षि
składa się z dwóch oddzielnych postaci:ष
, Devanagari List Ssa , aि
, Devanagari samogłoska Zaloguj I . Gdy są obok siebie w tej kolejności, graficznie łączą się w jedną postać, mimo że składają się z dwóch osobnych postaci.Natomiast kody znaków mają sens
👍
tylko wtedy, gdy są razem jako pojedynczy glif. Jeśli spróbujesz użyć łańcucha z jednym punktem kodowym bez drugiego, otrzymasz symbol nonsensowny:źródło
षि
tak naprawdę są to dwa znaki z odrębnymi punktami kodowymi połączone w jeden glif (jeden abstrakcyjny znak w rozumieniu człowieka). Jest to sprzeczne z👍
emoji, które samo w sobie jest kompletną postacią, mimo że jego punkt kodowy jest na tyle wysoki, że należy go podzielić na parę zastępczą. Uważam, że wyjaśnienie, które mogłoby pomóc w tej (poza tym wartościowej) odpowiedzi wiele.UTF-16 (kodowanie używane w ciągach znaków w js) używa jednostek 16-bitowych. Zatem każdy kod Unicode, który można przedstawić za pomocą 15 bitów, jest reprezentowany jako jeden punkt kodowy, a wszystko inne jako dwa, znane jako pary zastępcze . Iterator ciągów iteracje nad punktów kodowych.
UTF-16 na Wikipedii
źródło
Chodzi o kod za znakami. Niektóre są zakodowane w dwóch bajtach (UTF-16) i są interpretowane
Array.from
jako dwa znaki. Muszę sprawdzić listę znaków:http://www.fileformat.info/info/charset/UTF-8/list.htm
http://www.fileformat.info/info/charset/UTF-16/list.htm
Dla funkcji wyświetlającej kod szesnastkowy:
JavaScript: ciąg Unicode na szesnastkę
źródło