Javascript 내에서 문자열 객체를 어떻게 다룰까? 🙄

안녕하세요! 두두코딩 입니다 ✋
오늘은 Javascript String 개념에 대해 알아보겠습니다.

🖇1 소스코드에 마우스를 올리고 copy 버튼을 누를 경우 더 쉽게 복사할 수 있습니다!

궁금한 점, 보안점 남겨주시면 성실히 답변하겠습니다. 😁
+ 감상평 댓글로 남겨주시면 힘이됩니다. 🙇

Intro.

String 객체는 “표준 빌트인 객체”이다. 원시타입인 “문자열”을 다룰 때 유용한 프로퍼티메서드를 제공한다.

String 생성자 함수

표준 빌트인 객체인 String 객체는 생성자 함수 객체이다. 따라서, new 연산자와 함꼐 호출하여 String 인스턴스를 생성할 수 있다. String 함수를 new 연산자와 함께 호출할 경우 [[StringData]] 라는 내부 슬롯이 생성된다. 만약, 인자를 공백으로 전달할 경우 빈 문자열이 슬롯에 채워지게 되고, 전달한 인자가 있을 경우 해당 인자로 슬롯을 채우게 된다.

// length : 0, [[prototype]]: String, [[PrimitiveValue]]: ""
const strObj = new String();
console.log(strObj);

만약 new 연자 없이 String 객체로 직접 생성할 경우 인스턴스가 아닌 문자열을 반환한다.

// 숫자 타입 => 문자열 타입
String(1); // => "1"
String(486); // => "486"

// 불리언 타입 // => 문자열 타입
String(false); // => "false"
String(true); // => "true"

String length 프로퍼티

String 내 존재하는 프로퍼티로는 length 프로퍼티가 있다. 이름에서 알 수 있듯 문자열 길이에 대한 정보를 갖고 있는 프로퍼티이다.

'Hello'.length; // => 5
'안녕하세요!'.length; // => 6

String 메서드

String 내 문자열을 다룰 수 있는 메서드는 다양하게 존재한다. 보통 “문자열”을 담고 있는 자료구조 (e.g. 배열)같은 경우 원본 배열을 직접 변경 하는 경우와 임시 배열 생성 후 반환 하는 경우 두 가지로 나뉘게 된다.

String 객체 같은 경우 편리하게도 원본 배열을 직접 변경 하는 경우는 존재하지 않는다. 즉, 모든 String 내 존재하는 함수는 새로운 문자열을 생성해 데이터를 담아 반환하도록 구현>되어져 있다.

새로운 문자열을 생성해 반환한다는 말은 원본 배열을 건드릴 수 없다 즉, writable을 허락하지 않는다는 뜻이다. 아래와 같이 직접 PrototypeDescriptor를 확인해보면 writablefalse로 되어져 있는 것을 알 수 있다.

const strObj = new String('k');

// '0' : {value: 'k', writable: false, enumerable: true, configurable: false},
// 'length' : {value: 1, writable: false, enumerable: false, configurable: false}

console.log(Object.getOwnPropertyDescriptors(strObj));

지금부터 String 내 문자열을 다룰 수 있는 함수를 알아보자.

🌱 String.prototype.indexOf

indexOf 메서드는 대상 문자열에서 인수로 전달받은 문자열이 있을 경우 결과에서 첫 번째 인덱스를 반환한다.

const str = 'Hello world';

// 0 -> H 1 -> e 2 -> l
str.indexOf('l'); // -> 2

// or을 검색해 첫 번째 인덱스 반환
str.indexOf('or'); // -> 7

// 없을 경우 -1 반환
str.indexOf('x'); // -> -1

보통 아래와 같이 문자열 내 내가 원하는 데이터가 있나 없나를 검색할 때 많이 사용한다.

if (str.indexOf('Hello') !== -1) {
  // -1 이 아니라는 점은 값이 있다는 것.
  // 내가 원하는 작업 수행
}

하지만, “-1” 이라는 값을 통해 검사를 하는게 가독성 적으로 좋지 않아 효율을 위해 ES6에서는 includes 라는 함수를 추가했다.

if (str.includes('Hello')) {
  // 있을 경우 true, 없을 경우 false..
}

🌱 String.prototype.search

search 메서드는 정규 표현식을 활용해 매치된 값을 찾을 때 사용하는 함수이다.

const str = 'Hello worlds';

// o라는 표현식을 찾아라.
str.search(/o/); // -> 4

🌱 String.prtotype.startsWith | String.prototype.endsWith

ES6 에서 도입된 함수로 String 객체의 인자로 전달된 값이 처음으로 시작하는지 혹은 끝나는지 확인할 때 사용하는 함수이다.

const str = 'Hello world';

str.StarsWith('He'); // true
str.EndsWith('ld'); // true

// 만약 인자 값과 시작 값 혹은 끝 값이 다를 경우 "-1" 반환함.

위 함수와 같이 검색하는 함수는 2번째 인자로 “시작점”을 선택하게 해준다. (최적화를 위해) 따라서, 2번째 인자로 시작위치를 전달하면 해당 위치 기준부터 값을 찾도록 한다.

str.startsWith('He',5); // false

🌱 String.prototype.substring

Substring 메서드는 String 내 존재하는 문자열을 전달받은 인자 기준으로 추출해 반환하는 함수이다.

아래의 예시를 통해 무슨 말인지 확인해보자.

const str = 'Hello world';

// 인덱스를 1 부터 인덱스 4 이전 부분까지 부분 문자열을 반환함.
str.substring(1,4);

substring

위 그림과 같이, 전달된 인자를 기준으로 문자를 추출해 반환하는데 마지막 인자 이전까지의 값을 추출해 반환한다는 점을 기억하자.

substring 같은 경우 사용자를 위해 예외처리를 몇 가지 해두었다.

  1. 두번째 인자 전달 안할 경우
    • 마지막 문자 값 까지 추출해 반환
  2. 첫번째 인수 > 두 번째 인수
    • 인수 교환함.
  3. 인수 < 0
    • 0으로 치환함.
  4. 인수 > 문자열 길이
    • 인수를 문자열 길이로 치환함.
const str = 'Hello World';

// 인수 교환일어남
str.substring(4, 1); // 'ell'

// 인수 < 0 -> 0으로 치환
str.substring(-2); // 'Hello World'

// 인수 > 문자열 길이 -> 문자열 길이로 치환
str.substring(1, 100); // 'ello World'

🌱 String.prototype.slice

slice 메서드 같은 경우 substring과 동일하게 동작한다. 다만, 음수일 경우 0으로 치환하는 것이 아니라 값의 끝에서 부터 offset을 적용해 계산한다. 예를 들면 -5일 경우 끝에서 5만큼 떨어진 값을 구한다.

const str = 'hello world';

// 0으로 취급 됨.
str.substring(-5); // 'hello world'

// world
str.slice(-5);

🌱 String.prototype.toUpperCase | String.prototype.toLowerCase

메소드 이름 그대로 “대문자” 혹은 “소문자”로 문자열을 바꿀 때 사용한다.

const str = 'Hello world';

str.toUpperCase();
str.toLowerCase();

🌱 String.prototype.trim

trim 메서드 같은 경우 “공백 문자” 가 있을 경우 제거한 문자열을 반환할 때 사용한다.

const str = '           foo      ';

console.log(str.trim());

console.log(str.trimStart());
console.log(str.trimEnd());

trimStart()trimEnd() 같은 경우 시작점 부터 공백 제거 혹은 끝점 부터 공백제거 할때 사용한다.

🌱 String.prototype.replace

replace 메서드는 문자열에서 첫 번째 인자로 전달받은 문자열 혹은 정규표현식을 활용해 치환된 문자열을 반환하는 함수이다.

const str = 'Hello World';

str.replace('World', 'Kim'); // 'Hello Kim';

정규표현식을 사용했을 경우는 다음과 같다.

const str = 'Hello Hello';

// 'hello' 대소문자 구별하지 않고 전체 검색
str.replace(/hello/gi, 'Kim'); // 'Kim Kim'

🌱 String.prototype.split

split 메서드는 문자열에서 첫 번째 인수로 전달한 문자열 혹은 정규 표현식을 검색하여 문자열을 구분한 후 분리된 각 문자열로 이루어진 배열을 반환하는 함수이다.

const str = 'How are you doing?';

// 공백 기준으로 문자열을 나눠 배열에 담아 반환
str.split(' ');

// \s는 여러 가지 공백 문자 (스페이스, 탭 등)을 의미함.
// 공백문자 기준으로 문자을 나눠 배열에 담아 반환
str.split(/\s/);

// 빈 문자열 전달 시 문자를 단어로 쪼개서 반환함.
str.split('');

해당 함수 같은 경우 배열로 반환하기 때문에 array의 함수를 사용해 역순으로 문자열을 뒤집도록 만들 수 있다.


function reverseString(str) {
  // split은 인자를 기준으로 문자열을 분리해 배열로 반환
  // reverse는 배열을 뒤집는 함수
  // join은 배열을 문자열화 하는 함수
  return str.split('').reverse().join('');
}

console.log(reverseString('Hello world!'));