문자열 객체

img


JavaScript String



String 생성자 함수

  • 표준 빌트인 객체인 String 객체는 생성자 함수 객체이다.
  • 따라서 new 연산자와 함께 호출하여 String 인스턴스를 생성할 수 있다.
  • String 생성자 함수에 인수를 전달하지 않고 new 연산자와 함께 호출하면 [[StringData]] 내부 슬롯에 빈 문자열을 할당한 String 래퍼 객체를 생성한다.
1
2
3
4
const strObj = new String('Lee');
console.log(strObj);
// String {0: "L", 1: "e", 2: "e", length: 3, [[PrimitiveValue]]: "Lee"}
strObj.valueOf(); //'Lee'

위 예제를 크롬 브라우저의 개발자 도구에서 실행해보면 [[PrimitiveValue]]라는 프로퍼티가 보인다.
이는 [[StringData]] 내부 슬롯을 가리킨다. ES5에서는 [[StringData]]을 [[PrimitiveValue]]이라 불렸다.

  1. String 생성자 함수에 문자열을 인수로 전달 ( 문자열이 아니라면 문자열로 강제 변환한다. )
  2. [[StringData]] 내부 슬롯에 인수로 전달받은 문자열을 할당
  3. String 래퍼 객체를 생성

문자열은 유사배열 객체 + 이터러블

배열과 유사하게 인덱스를 사용하여 각 문자에 접근이 가능하다.

1
console.log(strObj[0]); // L

문자열 명시적 타입 변환 (new 없이 사용했을 때)

명시적 타입 변환 : new 연산자를 사용하지 않고 String 생성자 함수를 호출하면 String 인스턴스가 아닌 문자열을 반환한다.

1
2
3
4
5
6
7
8
// 숫자 타입 => 문자열 타입
String(1); // -> "1"
String(NaN); // -> "NaN"
String(Infinity); // -> "Infinity"

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

length 프로퍼티

length 프로퍼티는 문자열의 문자 개수를 반환한다.
문자열 레퍼 객체는 배열과 마찬가지로 length 프로퍼티를 갖는다.

1
2
'Hello'.length;    // -> 5
'안녕하세요!'.length; // -> 6

그리고 인덱스를 나타내는 숫자를 프로퍼티 키로, 각 문자를 프로퍼티 값으로 가지므로 문자열 레퍼 객체는 유사 배열 객체이다.

SSTTT


String 메서드

String 객체의 모든 메소드는 언제나 새로운 문자열을 반환한다. 즉, 원본 문자열에 영향을 주지 않는다.
문자열은 변경 불가능한 원시 값이다.


indexOf

  • 첫번쨰 인수로 전달한 문자열을 검색해 첫번쨰 인덱스를 반환. 검색 실패시 -1을 반환
  • 두번째 인수는 생략가능. 시작할 인덱스를 전달 가능하다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const str = 'Hello World';

// 문자열 str에서 'l'을 검색하여 첫번째 인덱스를 반환한다.
let index = str.indexOf('l');
console.log(index); // 2

// 문자열 str에서 'or'을 검색하여 첫번째 인덱스를 반환한다.
index = str.indexOf('or');
console.log(index); // 7

// 문자열 str에서 'x'를 검색하여 첫번째 인덱스를 반환한다.
// 검색에 실패하면 -1을 반환한다.
index = str.indexOf('x');
console.log(index); // -1

// 문자열 str의 인덱스 3부터 'l'을 검색하여 첫번째 인덱스를 반환한다.
index = str.indexOf('l', 3);
console.log(index); // 3

includes

  • 첫번쨰 인수로 전달한 문자열이 포함되어 있는지 확인하여 그 결과를 true 또는 false로 반환한다.
  • 두번째 인수는 생략가능. 시작할 인덱스를 전달 가능하다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const str = 'Hello world';

str.includes('Hello'); // -> true
str.includes(''); // -> true
str.includes('x'); // -> false
str.includes(); // -> false

// String.prototype.indexOf 메소드로 대체할 수 있다.
console.log(str.indexOf('hello')); // 0

// 문자열 str의 인덱스 3부터 'l'이 포함되어 있는지 확인
let index = str.includes('l', 3);
console.log(index); // true

index = str.includes('H', 3);
console.log(index); // false

charAt

  • charAt 메소드는 인수로 전달한 인덱스에 위치한 문자를 반환한다.
  • 인덱스는 문자열의 범위, 즉 0 ~ (문자열 길이 - 1) 사이의 정수이어야 한다.
  • 인덱스가 문자열의 범위를 벗어난 정수인 경우, 빈문자열을 반환한다.
1
2
3
4
5
const str = 'Hello';

for (let i = 0; i < str.length; i++) {
console.log(str.charAt(i)); // H e l l o
}

replace

  • 원본 문자열을 변경한다.
  • 첫번째 인수 - 문자열 또는 정규 표현식 : 검색할 문자열 , 여러개인 경우 1개만 반환
  • 두번째 인수 - 문자열 또는 치환 함수 : 바꿀 문자열 , 특수패턴 : $&는 검색된 문자열을 의미
  • 정규표현식을 인수로 받을 수 있다.
1
2
3
4
const str = 'Hello world';

// 첫번째로 검색된 문자열만 대체하여 새로운 문자열을 반환한다.
console.log(str.replace('world', 'Lee')); // Hello Lee

문자열.match(정규표현식)은 해당 정규표현식 조건에 해당되는 문자열을 찾아서 반환한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// camelCase => snake_case
function camelToSnake(camelCase) {
// /.[A-Z]/g => 문자와 대문자로 이루어진 문자열 검색
// 두번째 인수로 치환 함수를 전달할 수 있다.
return camelCase.replace(/.[A-Z]/g, match => {
console.log(match); // 'oW'
return match[0] + '_' + match[1].toLowerCase();
});
}

const camelCase = 'helloWorld';
camelToSnake(camelCase); // -> 'hello_world'

// snake_case => camelCase
function snakeToCamel(snakeCase) {
// /_[a-z]/g => _와 소문자로 이루어진 문자열 검색
// 두번째 인수로 치환 함수를 전달할 수 있다.
return snakeCase.replace(/_[a-z]]/g, match => {
console.log(match); // '_w'
return match[1].toUpperCase();
}); // helloWorld
}

const snakeCase = 'hello_world';
snakeToCamel(snakeCase); // -> 'helloWorld'

split

  • 원본 문자열은 변경되지 않는다.
  • 첫번째 인수로 전달한 문자열 또는 정규표현식을 대상 문자열에서 검색하여 문자열을 구분한 후 분리된 각 문자열로 이루어진 배열을 반환한다.
1
2
3
4
5
6
/**
* @param {string | RegExp} [separator] - 구분 대상 문자열 또는 정규표현식
* @param {number} [limit] - 구분 대상수의 한계를 나타내는 정수
* @return {string[]}
*/
str.split([separator[, limit]])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const str = 'How are you doing?';

// 공백으로 구분(단어로 구분)하여 배열로 반환한다
console.log(str.split(' ')); // [ 'How', 'are', 'you', 'doing?' ]

// 정규 표현식
console.log(str.split(/\s/)); // [ 'How', 'are', 'you', 'doing?' ]

// 인수가 없는 경우, 대상 문자열 전체를 단일 요소로 하는 배열을 반환한다.
console.log(str.split()); // [ 'How are you doing?' ]

// 각 문자를 모두 분리한다
console.log(str.split('')); // [ 'H','o','w',' ','a','r','e',' ','y','o','u',' ','d','o','i','n','g','?' ]

// 공백으로 구분하여 배열로 반환한다. 단 요소수는 3개까지만 허용한다
console.log(str.split(' ', 3)); // [ 'How', 'are', 'you' ]

// 'o'으로 구분하여 배열로 반환한다.
console.log(str.split('o')); // [ 'H', 'w are y', 'u d', 'ing?' ]

substring || slice

  • 첫번째 인수의 값 부터 두번째 인수의 바로 전(두번쨰 인수는 미포함)까지 위치한 부분 문자열을 반환한다.
  • 두번쨰 인수는 생략이 가능하다. 첫번쨰 인수의 값부터 끝까지 반환한다.
  • 원본 배별은 변하지 않는다.
  • 인수가 0보다 작거나 NaN 일경우, 강제로 0 취급
  • 인수가 문자열의 길이보다 클 경우 그 인수는 문자열의 길이로 취급.
  • slice와 거의 동일하게 동작하나 slice는 음수일 경우 뒤부터 음수만큼 복사해서 반환한다.
1
2
3
4
5
6
7
8
9
const str = 'Hello World';

// 인덱스 1부터 인덱스 4 이전까지의 부분 문자열을 반환한다.
str.substring(1, 4); // -> ell
str.substring(1); // -> 'ello World'

str.substring(-5); // -> 'hello world'
// 뒤에서 5자리를 잘라내어 반환한다.
str.slice(-5); // ⟶ 'world'
img

trim

  • 대상 문자열 양쪽 끝에 있는 공백 문자를 제거한 문자열을 반환한다.
1
2
3
4
5
6
7
8
9
10
11
12
const str = '   foo  ';

console.log(str.trim()); // 'foo'

// String.prototype.replace
console.log(str.replace(/\s/g, '')); // 'foo'
console.log(str.replace(/^\s+/g, '')); // 'foo '
console.log(str.replace(/\s+$/g, '')); // ' foo'

// String.prototype.{trimStart,trimEnd} : Proposal stage 3
console.log(str.trimStart()); // 'foo '
console.log(str.trimEnd()); // ' foo'

repeat

  • 인수로 전달한 정수만큼 반복해 연결한 새로운 문자열을 반환한다.
  • 인수로 전달한 정수가 0이면 빈 문자열을 반환 , 음수면 RangeError 발생
1
2
3
4
5
6
7
const str = 'abc';

str.repeat(0); // -> ''
str.repeat(1); // -> 'abc'
str.repeat(2); // -> 'abcabc'
str.repeat(2.5); // -> 'abcabc' (2.5 → 2)
str.repeat(-1); // -> RangeError: Invalid count value

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

  • toUpperCase 메소드는 문자열의 모든 문자를 대문자로 변경하여 반환.
  • toLowerCase 메소드는 문자열의 모든 문자를 대문자로 변경하여 반환.
1
2
3
4
const str = 'hello world!';

str.toUpperCase(); // -> 'HELLO WORLD!'
str.toLowerCase(); // -> 'hello world!'

String.prototype.startsWith || String.prototype.endsWith

  • ES6에서 새롭게 도입된 startsWith / endsWith 메소드는 문자열이 인수로 전달한 문자열로 시작 / 끝 을 확인하여 그 결과를 true 또는 false로 반환한다.
  • startsWith 메소드의 2번째 인수로 검색을 시작할 인덱스를 전달할 수 있다.
  • endsWith 메소드의 2번째 인수로 검색할 문자열의 길이를 전달할 수 있다.
1
2
3
4
5
6
7
8
9
const str = 'Hello world';

// 문자열 str이 'He'로 시작하는지 확인
str.startsWith('He'); // -> true
// 문자열 str이 'x'로 시작하는지 확인
str.startsWith('x'); // -> false

// 문자열 str의 인덱스 5부터 시작하는 문자열이 ' '로 시작하는지 확인
str.startsWith(' ', 5); // -> true
1
2
3
4
5
6
7
8
9
const str = 'Hello world';

// 문자열 str이 'ld'로 끝나는지 확인
str.endsWith('ld'); // -> true
// 문자열 str이 'x'로 끝나는지 확인
str.endsWith('x'); // -> false

// 문자열 str의 처음부터 5자리까지('Hello')가 'lo'로 끝나는지 확인
str.endsWith('lo', 5); // -> true

Share