문자열의 메소드
대소문자 변경 : toLowerCase∙toUpperCase()
이 두 메소드는 원본 문자열을 수정하지 않고 대문자 혹은 소문자로 변환하여 새로운 문자열로 반환한다.
문자열 반복 : repeat()
repeat()은 문자열을 주어진 횟수만큼 반복해 붙인 새로운 문자열을 반환한다.
"abc".repeat(2); // 'abcabc'
공백 제거 : trim∙trimEnd∙trimStart()
trim()은 문자열 양 끝의 공백을 제거하면서 원본 문자열을 수정하지 않고 새로운 문자열을 반환한다. 만약 특정 방향의 공백만을 제거해야 한다면 trimEnd∙trimStart()를 사용할 수 있다.
const greeting = ' Hello world! ';
greeting.trim() // "Hello world!"
문자열 자르기 : substring()와 slice()
slice()는 배열의 메소드 그것과 완벽하게 동일하게 동작한다. substring()은 slice()와 거의 비슷하지만 몇 가지 차이가 있기는 하다. slice()의 경우 반드시 첫 번째 인자가 두 번째 인자보다 작아야 하지만, substring()의 경우에는 첫 번째 인자가 두 번째 인자보다 크다면 두 인자의 순서가 마치 바뀐 것처럼 동작한다.
let text = "Mozilla"
text.substring(5, 2) // => "zil"
text.slice(5, 2) // => ""
음수의 인자를 받는 경우에도 두 메소드는 동작에 차이를 보인다. substring()의 경우에는 음수의 인자를 0으로 취급한다. 반면 slice()의 경우 첫 번째 인자가 두 번째 인자보다 작다면 음수의 인덱스를 사용하여 문자열을 잘라낸다.
let text = "Mozilla"
text.substring(-5, -2) // => ""
text.slice(-5, -2) // => "zil"
문자열 채우기 : padStart∙padEnd()
이 두 메소드는 인자로 제공되는 문자열을 주어진 길이에 도달할 때까지 문자열의 앞 혹은 뒤에 반복한다.
const phoneNumber = "01000000000";
const last4Digits = phoneNumber.slice(-4);
last4Digits.padStart(phoneNumber.length, '*'); // "*******0000"
존재 유무 : includes()
includes()은 배열의 그것과 비슷하게 하나의 문자열을 받아서, 해당 문자열이 다른 문자열에 포함되어 있는지를 판별하고 그 결과를 적절하게 boolean으로 반환한다.
const sentence = 'The quick brown fox jumps over the lazy dog.';
sentence.includes('fox') // true
sentence.includes('wolf') // false
인덱스 조회 : indexOf∙lastIndexOf()와 search()
indexOf()는 배열의 그것과 비슷하게 문자열을 받아서, 해당 문자열과 일치하는 첫 번째 인덱스를 반환한다. 다만, 선택적으로 숫자형의 두 번째 인자를 제공할 수 있는데, 이를 통해 문자열의 시작이 아닌 특정 위치부터 조회가 가능하다. lastIndexOf()는 가장 마지막 인덱스를 반환한다는 차이만 있다.
const paragraph = "I think Ruth's dog is cuter than your dog!";
paragraph.indexOf("dog") // 15
paragraph.lastIndexOf("dog") // 38
paragraph.indexOf("dog", 20) // 38
search()는 비슷하지만 문자열 대신 정규식을 받는다. 특정 문자열에 정규식과 일치하는 항목이 포함되어있는지를 판별하고, 첫 번째로 일치하는 항목의 인덱스를 반환한다.
const paragraph = "I think Ruth's dog is cuter than your dog!";
const regex = /[^\w\s']/g
paragraph.search(regex) // 41
paragraph[paragraph.search(regex)] // "!"
문자열 조회 : charAt∙at()
이 두 메소드는 숫자를 인자로 받아 문자열의 해당 인덱스에 위치한 유니코드 단일문자를 반환한다. 차이가 있다면 at()은 배열의 그것과 동일하게 음수 인덱스를 받는다는 점이지만, charAt()은 음수 인덱스를 처리하지 못한다는 점이다.
const sentence = 'The quick brown fox jumps over the lazy dog.';
const index = -4;
sentence.charAt(index) // ""
sentence.at(index) // "d"
문자열의 시작과 끝 조회 : startsWith∙endsWith()
startsWith()은 어떤 문자열의 문자로 시작하는지를 확인하고 이 결과를 적절하게 boolean으로 반환한다. endsWith()은 어떤 문자열의 문자로 끝나는지를 확인한다. indexOf와 같이 둘 다 선택적으로 숫자형의 두 번째 인자를 제공할 수 있는데, 이를 통해 반드시 문자열의 시작이 아닌 특정 index가 어떻게 시작하는지를 확인할 수 있다.
const str1 = 'Saturday night plans';
const str2 = 'Cats are the best!';
str1.startsWith('Sat') // true
str1.startsWith('Sat', 3) // false
str2.endsWith('best!') // true
str2.endsWith('best', 17) // true
유니코드와 UTF-16
UTF-16는 유니코드 문자를 16비트(2바이트)로 인코딩하는 방식이다. 유니코드의 코드 포인트는 0x0000에서 0x10FFFF 사이에 분포되어 있는데, 이 중 가장 자주 사용되는 문자들은 16비트(2바이트)로 표현할 수 있다. 그러나 0x10000 이상의 코드 포인트를 표현하기 위해서는 16비트로는 부족하기 때문에 서로게이트 쌍(surrogate pair)이라는 개념이 필요하게 된다.
서로게이트 쌍은 UTF-16에서 하나의 유니코드 코드 포인트를 표현하기 위해 사용되는 두 개의 16비트 코드 유닛이다. 즉, 서로게이트 쌍은 두 개의 16비트 값으로 이루어진 조합으로, 이 조합이 하나의 유니코드 문자(코드 포인트)를 나타낸다. 따라서 서로게이트 쌍을 구성하는 글자들은 붙어있을 때만 의미가 있다. 또한, 서로게이트 쌍으로 인코딩된 기호의 길이는 2이다.
"𩷶".length // 2
일반적인 알파벳이나 한글을 유니코드로 치환하기 위해서는 charCodeAt∙fromCharCode()를 사용하지만, 이러한 서로게이트 쌍을 다루기 위해서는 codePointAt∙fromCodePoint()라는 특수한 메소드를 사용해야 한다. codePointAt()은 인덱스가 서러게이트 쌍의 첫 번째 유닛을 가리키면 전체 유니코드 코드 포인트를 반환한다.
"𩷶".codePointAt(0) // 171510
"𩷶".fromCodePoint(1) // 56822
서로게이트 쌍이 아닌 경우 codePointAt()와 charCodeAt() 어느쪽을 사용하든 같은 값을 반환한다. 따라서 특정 단어의 코드 포인트를 정확히 구하기 위해서는 codePointAt()과 fromCodePoint()를 사용하는 습관을 들이는 게 좋겠다.
const str = "abcd";
str.codePointAt(0) // 97
str.codePointAt(1) // 98
str.charCodeAt(0) // 97
str.charCodeAt(1) // 98
블로그의 정보
Ayden's journal
Beard Weard Ayden