String 메서드에 대하여

특정 글자에 접근

String.prototype.at(), String.prototype.charAt(), 그리고 인덱스로 직접 접근

  • 공통점

    • 인수로 숫자를 받으면 특정 글자를 반환한다.
      'string'.at(0); // s
      'string'.charAt(0); // s
      'string'[0]; // s
      
  • 차이점

    • at 메서드는 인수로 음수도 받을 수 있다.

      'string'.at(-1); // g
      
    • at 메서드와 인덱스로 직접 접근할 경우 인수가 범위를 초과하면 undefined를 반환하고 charAt 메서드는 빈 문자열을 반환한다.

      'string'.at(6); // undefined
      'string'[6]; // undefined
      
      'string'.charAt(6); // ""
      
    • charAt 메서드는 인수를 생략하면 0으로 설정된다.

      'string'.charAt(); // s
      

부분 문자열 찾기

String.prototype.search()String.prototype.indexOf()

  • 공통점

    • 인수로 받은 값에 첫번째로 매칭된 부분 문자열의 인덱스를 반환한다.
    • 찾지 못하면 -1을 반환한다.
  • 차이점

    • search 메서드는 인수로 정규식과 문자열을 받는다.

      'string'.search('str'); // 0
      'string'.search(/[s]/); // 0
      
      // 정규식에 g 플래그를 사용해도 똑같이 작동한다.
      'string'.search(/[s]/g); // 0
      
    • indexOf 메서드는 인수로 문자열을 받는다.

      'string'.search('str'); // 0
      

비트 NOT 연산자를 이용해서 -1을 0으로 바꾸기

if (~str.indexOf("example")) { ... }

String.prototype.includes(), String.prototype.startsWith(), 그리고 String.prototype.endsWith()

  • 공통점

    • 인수로 문자열을 받아서 해당 문자열의 존재 유무에 따른 불리언 값을 반환한다.
  • 차이점

    • includes 메서드는 전체 문자열에 포함되어 있는지를 기준으로 한다.
      'string'.includes('s'); // true;
      
    • startsWith 메서드는 시작부분과 일치 하는지를 기준으로 한다.
      'string'.startsWith('s'); // true;
      
    • endsWith 메서드는 끝부분과 일치 하는지를 기준으로 한다.
      'string'.endsWith('g'); // true;
      

String.prototype.match()

인수로 받은 정규식 혹은 문자열에 부합하는 첫번째 문자열을 찾아서 배열로 반환한다.
정규식에 g 플래그를 사용하면 부합하는 문자열을 전부 배열에 포함시켜서 반환한다.

'sssss'.match(/[s]/); // ['s', index: 0, input: 'sssss', groups: undefined]
'sssss'.match(/[s]/g); // ['s', 's', 's', 's', 's']

String.prototype.matchAll()

인수로 받은 정규식 혹은 문자열에 부합하는 문자열을 찾아서 이터레이터로 반환한다.
정규식에 g 플래그를 사용하지 않으면 에러를 던진다.

'sssss'.matchAll(/[s]/g); // RegExpStringIterator {}

부분 문자열 교체

String.prototype.replace()

첫번째 인수로 받은 정규식 혹은 문자열에 부합하는 첫번째 문자열을 찾아서 두번째 인수에 해당하는 문자열로 교체한다.
정규식에 g 플래그를 사용하면 replaceAll 메서드와 동일한 동작을 한다.

'sssss'.replace(/[s]/, 't'); // 'tssss'
'sssss'.replace(/[s]/g, 't'); // 'ttttt'

String.prototype.replaceAll()

첫번째 인수로 받은 정규식 혹은 문자열에 부합하는 문자열을 찾아서 두번째 인수에 해당하는 문자열로 전부 교체한다.
정규식에 g 플래그를 사용하지 않으면 에러를 던진다.

'sssss'.replaceAll('s', 't'); // 'ttttt'
'sssss'.replaceAll(/[s]/g, 't'); // 'ttttt'

부분 문자열 추출하기

String.prototype.slice()String.prototype.substring()

  • 공통점

    • 첫번째 인수부터 두번째 인수까지(미포함)에 해당하는 문자열을 반환한다.
      'string'.slice(0, 1); // 's'
      'string'.substring(0, 1); // 's'
      
  • 차이점

    • slice 메서드는 인수로 음수를 받을 수 있다.
      'string'.slice(-2, -1); // 'n'
      
    • substring 메서드는 첫번째 인수가 두번째 인수보다 커도 된다.
      'string'.substring(2, 0); // 'st'
      

구분자로 문자열 나누기

String.prototype.split

인수로 받은 문자열 혹은 정규식을 구분자로 하여 문자열을 나누고 배열로 반환하다.

'string'.split('r'); // ['st', 'ing']

인수로 빈 문자열을 받아서 한 글자씩 나눈 결과를 배열로 반환할 수 있지만 이모티콘이나 특수문자가 포함된 경우를 조심해야 한다.

'💩'.split(''); // ['\uD83D', '\uDCA9']

이러한 이유로 Array.from 메서드나 스프레드 연산자를 사용해야 한다.

Array.from('💩'); // ['💩']
[...'💩']; // ['💩']

문자열 채우기

String.prototype.padStart()String.prototype.padEnd()

  • 공통점

    • 두번째 인수로 받은 문자열을 채워서 첫번째 인수로 받은 수만큼의 길이를 가진 문자열을 반환한다.
  • 차이점

    • padStart 메서드는 왼쪽부터 채워나간다.
      '11'.padStart(5, '0'); // '00011'
      
    • padEnd 메서드는 오른쪽부터 채워나간다.
      '11'.padEnd(5, '0'); // '11000'
      

서로게이트 쌍

자바스크립트에서 특정 글자에 접근하거나 부분 문자열을 추출할때 서로게이트 쌍을 신경써야 한다.

'💩'.at(0); // \uD83D
'💩'.charAt(0); // \uD83D
'💩'[0]; // \uD83D

'💩'.slice(0, 1); // \uD83D
'💩'.substring(0, 1); // \uD83D

서로게이트 쌍이란?
유니코드 코드 포인트를 나타내기 위해 사용되는 특별한 두 개의 16비트 유니코드 단위다.
이모티콘이나 특수문자를 표현할때 사용된다.
High Surrogate(U+D800 ~ U+DBEF)와 Low Surrogate(U+DC00 ~ U+DFFF)가 결합하여 문자를 형성한다.

서로게이트 쌍을 고려한 slice 메서드를 구현하면 아래와 같다.

function slice(str, start, end) {
  return Array.from(str).slice(start, end).join('');
}