Array.from
ilk önce, varsa argümanın yinelemesini çağırmaya çalışır ve dizelerde yineleyiciler bulunur, bu nedenle çağırır String.prototype[Symbol.iterator]
, bu yüzden prototip yönteminin nasıl çalıştığına bakalım. Buradaki spesifikasyonda açıklanmıştır :
- Bırakalım O mu? RequireObjectCoercible (bu değer).
- Hadi olalım ? .ToString (O) olmasıdır.
- CreateStringIterator (S) öğesini döndürün.
CreateStringIterator
Sonunda bakmak sizi götürür 21.1.5.2.1 %StringIteratorPrototype%.next ( )
, bu da şunları yapar:
- Bırak cp olsun! CodePointAt (s, konum).
- ResultsString öğesinin, kod birimi dizin konumundayken başlayarak cp. [[CodeUnitCount]] ardışık kod birimlerini içeren String değeri olsun.
- O. [[StringNextIndex]] konumunu + cp. [[CodeUnitCount]] olarak ayarlayın.
- CreateIterResultObject öğesini döndürür (sonuçString, yanlış).
CodeUnitCount
Eğer ilgilendiğiniz şeydir bu sayı gelir. CodePointAt :
- Önce dize içindeki dizin konumundaki kod birimi olsun.
- Sayısal değeri ilk olan kod noktası cp olsun.
İlk önce önde gelen vekil veya takip eden vekil değilse,
a. Kaydı Döndür { [[CodePoint]]: cp, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: false }
.
İlk önce bir vekil veya konum + 1 = boyutsa, o zaman
Kaydı Döndür { [[CodePoint]]: cp, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: true }
.
İkincisi, dize içindeki dizin konumunda + 1 olan kod birimi olsun.
İkincisi sondaki bir vekil değilse,
a. Kaydı Döndür { [[CodePoint]]: cp, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: true }
.
Cp olarak ayarlayın! UTF16DecodeSurrogatePair (birinci, ikinci).
Kaydı Döndür { [[CodePoint]]: cp, [[CodeUnitCount]]: 2, [[IsUnpairedSurrogate]]: false }
.
Bu nedenle, bir dize üzerinden yineleme Array.from
yaparken, yalnızca söz konusu karakter bir vekil çiftin başlangıcı olduğunda CodeUnitCount 2 değerini döndürür. Yedek çiftler olarak yorumlanan karakterler burada açıklanmıştır :
Bu tür işlemler, 0xD800 - 0xDBFF dahilinde sayısal bir değere sahip her kod birimine (Unicode Standard tarafından öncü vekil olarak veya daha resmi olarak yüksek vekil kod birimi olarak tanımlanır) ve sayısal değere sahip her kod birimine özel işlem uygular. Aşağıdaki kuralları kullanarak 0xDC00 ila 0xDFFF (izleyen vekil olarak tanımlanır veya daha resmi olarak düşük vekil kod birimi olarak tanımlanır).
षि
bir vekil çift değildir:
console.log('षि'.charCodeAt()); // First character code: 2359, or 0x937
console.log('षि'.charCodeAt(1)); // Second character code: 2367, or 0x93F
Ama 👍
karakterleri:
console.log('👍'.charCodeAt()); // 55357, or 0xD83D
console.log('👍'.charCodeAt(1)); // 56397, or 0xDC4D
İlk karakter kodu, '👍'
altıgen olarak, 0xD800 to 0xDBFF
önde gelen taşıyıcıların aralığı içinde olan D83D'dir . Buna karşılık, ilk karakter kodu 'षि'
çok daha düşüktür ve değildir. Yani 'षि'
bölünür, ama '👍'
olmaz.
षि
İki ayrı karakterden oluşur: ष
, Devanagari Harf Ssa ve ि
, Devanagari Sesli I yapınız . Bu sırayla yan yana olduklarında, iki ayrı karakterden oluşmasına rağmen görsel olarak tek bir karakterde grafik olarak birleştirilirler.
Buna karşılık, karakter kodları 👍
sadece tek bir glif olarak birlikte olduğunda anlamlıdır. Herhangi bir kod noktası diğeri olmadan bir dize kullanmaya çalışırsanız, saçma bir sembol alırsınız:
console.log('👍'[0]);
console.log('👍'[1]);