Saya telah bermain-main dengan JS dan tidak tahu bagaimana JS memutuskan elemen mana yang akan ditambahkan ke array yang dibuat saat menggunakan Array.from()
. Sebagai contoh, emoji 👍 berikut memiliki nilai length
2, karena terdiri dari dua titik kode, tetapi, Array.from()
memperlakukan dua titik kode ini sebagai satu, memberikan array dengan satu elemen:
const emoji = '👍';
console.log(Array.from(emoji)); // Output: ["👍"]
Namun, beberapa karakter lain juga memiliki dua titik kode seperti karakter ini षि
(juga memiliki a .length
2). Namun, Array.from
jangan "mengelompokkan" karakter ini dan malah menghasilkan dua elemen:
const str = 'षि';
console.log(Array.from(str)); // Output: ["ष", "ि"]
Pertanyaan saya adalah: Apa yang menentukan apakah karakter dipecah (seperti pada contoh dua) atau diperlakukan sebagai satu elemen tunggal (seperti pada contoh satu) ketika karakter terdiri dari dua titik kode?
sumber
षि
adalah 2 karakter yang terpisahlength
. Iterator atau bahkanSet
tidak bekerja dengan ituJawaban:
Array.from
pertama-tama mencoba untuk memanggil iterator dari argumen jika ada, dan string memang memiliki iterator, jadi ia memanggilString.prototype[Symbol.iterator]
, jadi mari kita mencari cara kerja metode prototipe. Ini dijelaskan dalam spesifikasi di sini :Melihat ke atas pada
CreateStringIterator
akhirnya membawa Anda ke21.1.5.2.1 %StringIteratorPrototype%.next ( )
, yang artinya:Inilah
CodeUnitCount
yang Anda minati. Nomor ini berasal dari CodePointAt :Jadi, ketika iterasi dengan string
Array.from
, ia mengembalikan CodeUnitCount 2 hanya ketika karakter yang dimaksud adalah awal dari pasangan pengganti. Karakter yang ditafsirkan sebagai pasangan pengganti dijelaskan di sini :षि
bukan pasangan pengganti:Tapi
👍
karakternya adalah:Kode karakter pertama
'👍'
adalah, dalam hex, D83D, yang berada dalam jangkauan0xD800 to 0xDBFF
surrogate terkemuka. Sebaliknya, kode karakter pertama'षि'
jauh lebih rendah, dan tidak. Jadi'षि'
mendapat terpisah, tetapi'👍'
tidak.षि
terdiri dari dua karakter yang terpisah:ष
, Devanagari Surat Ssa , danि
, Devanagari Vokal Sign saya . Ketika bersebelahan dalam urutan ini, mereka digabungkan secara grafis menjadi satu karakter secara visual, meskipun terdiri dari dua karakter yang terpisah.Sebaliknya, kode karakter
👍
hanya masuk akal ketika bersama sebagai mesin terbang tunggal. Jika Anda mencoba menggunakan string dengan salah satu titik kode tanpa yang lain, Anda akan mendapatkan simbol omong kosong:sumber
षि
sebenarnya adalah dua karakter dengan titik kode berbeda digabungkan untuk membentuk satu mesin terbang (satu karakter abstrak , sebagaimana dipahami oleh manusia). Ini berbeda dengan👍
emoji, yang merupakan karakter lengkap di dalam dan dari dirinya sendiri, meskipun titik kodenya cukup tinggi sehingga harus dipisah menjadi pasangan pengganti. Saya percaya klarifikasi yang dapat membantu ini (jika tidak berharga) menjawab banyak.UTF-16 (pengkodean yang digunakan untuk string dalam js) menggunakan unit 16bit. Jadi setiap unicode yang dapat direpresentasikan menggunakan 15 bit direpresentasikan sebagai satu titik kode, yang lainnya sebagai dua, yang dikenal sebagai pasangan pengganti . The iterator dari string iterates atas poin kode.
UTF-16 di Wikipedia
sumber
Ini semua tentang kode di belakang karakter. Beberapa dikodekan dalam dua byte (UTF-16) dan ditafsirkan
Array.from
sebagai dua karakter. Harus memeriksa daftar karakter:http://www.fileformat.info/info/charset/UTF-8/list.htm
http://www.fileformat.info/info/charset/UTF-16/list.htm
Untuk fungsi yang menampilkan kode hex:
Javascript: String Unicode ke hex
sumber