JS로 놀고 있었고 JS가 사용할 때 생성 된 배열에 추가 할 요소를 결정하는 방법을 알 수 없습니다 Array.from()
. 예를 들어 다음 emoji ?은 length
두 개의 코드 포인트로 구성되어 있으므로 2의 a 를 갖지만 Array.from()
이 두 코드 포인트를 하나로 취급하여 하나의 요소가있는 배열을 제공합니다.
const emoji = '?';
console.log(Array.from(emoji)); // Output: ["?"]
그러나 일부 다른 문자에는이 문자와 같은 두 개의 코드 포인트 षि
가 있습니다 (또한 .length
2가 있음). 그러나이 Array.from
캐릭터를 “그룹화”하지 않고 대신 두 가지 요소를 생성합니다.
const str = 'षि';
console.log(Array.from(str)); // Output: ["ष", "ि"]
내 질문은 : 문자가 두 개의 코드 포인트로 구성되어있을 때 문자가 (예 2와 같이) 분리되거나 하나의 단일 요소로 처리되는지 여부를 결정하는 것은 무엇입니까?
답변
Array.from
먼저 인수 반복자가 있으면 인수의 반복자를 호출하려고 시도하고 문자열에 반복자가 있으므로를 호출 String.prototype[Symbol.iterator]
하므로 프로토 타입 메소드의 작동 방식을 살펴 보겠습니다. 여기 사양에 설명되어 있습니다 :
- O하자? RequireObjectCoercible (이 값).
- S하자? ToString (O).
- CreateStringIterator (S)를 반환합니다.
찾는 것은 CreateStringIterator
결국 당신을 데려갑니다 21.1.5.2.1 %StringIteratorPrototype%.next ( )
.
- cp가되게하십시오! CodePointAt (s, 위치).
- resultString을 인덱스 위치에서 코드 단위로 시작하는 cp. [[CodeUnitCount]] 개의 연속 코드 단위를 포함하는 문자열 값으로 설정하십시오.
- O. [[StringNextIndex]]를 + cp. [[CodeUnitCount]]로 설정하십시오.
- CreateIterResultObject (resultString, false)를 반환합니다.
은 CodeUnitCount
관심있는 것입니다이 숫자에서 온다. CodePointAt :
- 먼저 문자열 내에서 인덱스 위치의 코드 단위로 사용하십시오.
- cp를 숫자 값이 첫 번째 값인 코드 포인트로 지정하십시오.
첫 번째가 주요 대리 또는 후행 대리가 아닌 경우
ㅏ. 기록을 반환하십시오
{ [[CodePoint]]: cp, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: false }
.먼저 후행 대리 또는 위치 + 1 = 크기 인 경우
a. 기록을 반환하십시오
{ [[CodePoint]]: cp, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: true }
.두 번째로 문자열 내에서 인덱스 위치 + 1의 코드 단위로 사용하십시오.
두 번째가 후행 대리가 아닌 경우
ㅏ. 기록을 반환하십시오
{ [[CodePoint]]: cp, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: true }
.cp를!로 설정하십시오. UTF16DecodeSurrogatePair (첫 번째, 두 번째).
기록을 반환하십시오
{ [[CodePoint]]: cp, [[CodeUnitCount]]: 2, [[IsUnpairedSurrogate]]: false }
.
Array.from
따라서을 사용하여 문자열을 반복 하면 해당 문자가 서로 게이트 쌍의 시작 인 경우에만 CodeUnitCount가 2로 반환됩니다. 서로 게이트 쌍으로 해석되는 문자는 다음과 같습니다 .
이러한 작업은 0xD800 ~ 0xDBFF 범위의 숫자 값을 가진 모든 코드 단위 (유니 코드 표준에 의해 선행 대리 또는보다 공식적으로 높은 대리 코드 단위 로 정의 됨) 와 숫자 값을 가진 모든 코드 단위에 특별한 처리를 적용 합니다. 다음 규칙을 사용하여 0xDC00 ~ 0xDFFF (후미 대리로 정의되거나보다 공식적으로 저 대리 코드 단위로 정의) 범위에서 .. :
षि
대리 쌍이 아닙니다.
console.log('षि'.charCodeAt()); // First character code: 2359, or 0x937
console.log('षि'.charCodeAt(1)); // Second character code: 2367, or 0x93F
그러나 ?
의 캐릭터는 다음과 같습니다.
console.log('?'.charCodeAt()); // 55357, or 0xD83D
console.log('?'.charCodeAt(1)); // 56397, or 0xDC4D
첫 번째 문자 코드는 '?'
16 진수로 D83D이며, 이는 0xD800 to 0xDBFF
주요 대리자 의 범위 내에 있습니다. 반대로 첫 번째 문자 코드 'षि'
는 훨씬 낮고 그렇지 않습니다. 따라서 'षि'
분리되지만 분리 '?'
되지 않습니다.
षि
두 개의 문자로 구성되어 ष
, 데바 나가리 문자 SSA 하고 ि
, 데바 나가리 모음 내가 서명 . 이 순서대로 나란히 놓이면 두 개의 개별 문자로 구성되어 있음에도 불구하고 시각적으로 단일 문자로 그래픽으로 결합됩니다.
대조적으로, 문자 코드 는 단일 글리프로 함께 사용될 ?
때만 의미가 있습니다. 다른 코드 포인트없이 코드 포인트가 포함 된 문자열을 사용하려고하면 넌센스 기호가 나타납니다.
console.log('?'[0]);
console.log('?'[1]);
답변
UTF-16 (js의 문자열에 사용되는 인코딩)은 16 비트 단위를 사용합니다. 따라서 15 비트를 사용하여 표현할 수있는 모든 유니 코드는 하나의 코드 포인트로 표현되며 다른 모든 것은 2로 표시되며 서로 게이트 쌍이라고 합니다. 문자열의 반복자는 코드 포인트 반복 할.
답변
문자 뒤의 코드에 관한 것입니다. 일부는 2 바이트 (UTF-16)로 코딩 Array.from
되며 두 문자로 해석됩니다 . 문자 목록을 확인해야합니다.
http://www.fileformat.info/info/charset/UTF-8/list.htm
http://www.fileformat.info/info/charset/UTF-16/list.htm
function displayHexUnicode(s) {
console.log(s.split("").reduce((hex,c)=>hex+=c.charCodeAt(0).toString(16).padStart(4,"0"),""));
}
displayHexUnicode('षि');
console.log(Array.from('षि').forEach(x => displayHexUnicode(x)));
function displayHexUnicode(s) {
console.log(s.split("").reduce((hex,c)=>hex+=c.charCodeAt(0).toString(16).padStart(4,"0"),""));
}
displayHexUnicode('?');
console.log(Array.from('?').forEach(x => displayHexUnicode(x)));
16 진 코드를 표시하는 기능 :