[32장] String
1. String 생성자 함수
String 객체는 표준 빌트인 객체이면서 생성자 함수 객체다.
즉, new 연산자로 인스턴스 생성 가능
new 연산자와 함께 인수를 전달하면 [[StringData]] 내부 슬롯에
문자열을 할당한 String 래퍼 객체를 생성한다
래퍼 객체는 유사 배열 객체이면서 이터러블이다. 즉, 배열처럼
- length 프로퍼티
- 인덱스를 나타내는 프로퍼티 키 (숫자 형식의 문자열)
- 각 문자를 프로퍼티 값으로 갖는다
단, 문자열은 원시 값이므로 변경 불가능하다(에러가 발생하는건 아니지만)
const strObj = new String('Lee');
// { 0: "l" 1: "e" 2: "e" length: 3 }
Object.getOwnPropertyDescriptors(strObj);
// {0: {…}, 1: {…}, 2: {…}, length: {…}}
// 0: {value: 'l', writable: false, enumerable: true, configurable: false}
// 1: {value: 'e', writable: false, enumerable: true, configurable: false}
// 2: {value: 'e', writable: false, enumerable: true, configurable: false}
// length: {value: 3, writable: false, enumerable: false, configurable: false}
// [[Prototype]]: Object
strObj[0] = 'S';
// 이렇게 바꾸려고 해도
// 'See'로 바뀌지 않음
new 연산자 없이 일반 함수로 호출하면 문자열을 퉤 내뱉어주기 때문에
이걸로 명시적 타입 변환을 하기도 한다
String(NaN); // 'NaN'
string(Infinity) // 'Infinity'
2. length 프로퍼티
문자열의 문자 개수를 반환
3. String 메서드
배열은 원본 배열을 직접 변경하는 메서드와 그렇지 않은 메서드가 있는데(mutator method/accessor method), String 객체에선 원본 String 래퍼 객체를 직접 변경하는 메서드는 존재하지 않는다. 즉, String 객체의 메서드는 결과로 언제나 새로운 문자열 반환.
why?
문자열은 변경 불가능한(immutable) 원시값이기 때문에 String 래퍼 객체도 읽기 전용(read-only)객체로 제공된다.
3.1 String.prototype.indexOf
인수로 전달받은 문자열의 첫 번째 인덱스를 반환. 없으면 -1
('Hello world').indexOf( 'l' ); // 2
indexOf로 특정 문자열이 존재하는지 확인할 순 있지만
그냥 String.prototype.includes 메서드 쓰셈. 그게 더 가독성 좋음
3.2 String.prototype.search
인수로 정규 표현식을 전달받아 매치되는 문자열의 인덱스를 반환. 없으면 -1
('Hello world').search( /o/ ); // 4
('Hello world').search( /x/ ); // -1
3.3 String.prototype.includes (ES6)
인수로 전달받은 문자열이 포함돼있는지 확인, boolean으로 반환
includes( 찾을문자 [, 어디서부터 검색?] )
3.4 String.prototype.startsWith
인수로 전달받은 문자열로 시작하는지 확인, boolean으로 반환
startsWith( 찾을문자 [, 어디서부터 검색?] )
3.5 String.prototype.endsWidth
인수로 전달받은 문자열로 끝나는지 확인, boolean으로 반환
endsWith( 찾을문자 [, 어디까지 검색?] )
3.6 String.prototype.charAt
인수로 전달받은 인덱스에 위치한 문자를 검색&반환
('Hello world').charAt( 4 ) // 'o'
3.7 String.prototype.substring
substring(a, b)
인덱스 a부터 b 이전까지의 문자열을 반환.
b 생략시 a부터 끝까지 검색함.
('Hello world').substring( 0,4 ) // 'Hell'
const str = 'Hello world';
str.substring( 0, str.indexOf(' ') ); // Hello
str.substring( str.indexOf(' ')+1, str.length ); // world
3.8 String.prototype.slice
substring이랑 똑같은데 인수로 음수도 전달할 수 있는 메서드
3.9 String.prototype.toUpperCase
3.10 String.prototype.toLowerCase
3.11 String.prototype.trim
대상 문자열 앞뒤에 공백을 제거해줌
문자열 앞의 공백이나 뒤의 공백만 제거하고 싶으면
trimStart / trimEnd 메서드 쓰셈
* 앞이고 뒤고 나발이고 그냥 공백 전부 제거하고싶으면 정규 표현식 ㄱㄱ
(' Hell o w o rld ').replace(/\s/g,'');
3.12 String.prototype.repeat (ES6)
인수로 정수를 전달하면 그만큼 문자열을 반복연결해줌
('안녕').repeat(3) // 안녕안녕안녕
3.13 String.prototype.replace
문자열이나 정규 표현식을 기준으로 검색 후, 다른 문자열로 치환
replace( regexp|substr, newSubstr|function)
const str = 'Hello world';
str.replace(/hello/gi, '뭠마') // 뭠마 world
두번째 인수로 치환 함수도 전달할 수 있는데,
첫번째 인수에서 검색된 결과물을 함수의 인수로 전달하면서 호출하는 개념
예제) 카멜->스네이크 / 스네이크->카멜케이스
function camelToSnake(camelCase) {
return camelCase.replace(/.[A-Z]/g, match => {
return `${match[0]}_${match[1].toLowerCase()}`;
});
}
function snakeToCamel(snakeCase) {
return snakeCase.replace(/_[a-z]/g, match => {
return `${match[1].toUpperCase()}`;
});
}
console.log(camelToSnake('repalceAll')); // replace_all
console.log(snakeToCamel('repalce_all')); // replaceAll
3.14 String.prototype.split
문자열이나 정규 표현식을 기준으로 문자열을 쪼갠 후 배열로 반환
split( [separator [, limit] ] )
- separator : 쪼갤 기준
- limit : 배열 길이
const str = 'How are you doing?'
str.split();
str.split('');
str.split(' ');
str.split(/\s/);
str.split(/\s/, 2);
// ['How are you doing?']
// ['H', 'o', 'w', ' ', 'a', 'r', 'e', ' ', 'y', 'o', 'u', ' ', 'd', 'o', 'i', 'n', 'g', '?']
// ['How', 'are', 'you', 'doing?']
// ['How', 'are', 'you', 'doing?']
// ['How', 'are']
3.15 String.prototype.charCodeAt
- 전달받은 인덱스에 위치한 문자열을 UTF-16코드로 변환한다
- UTF-16 코드는 0~65535사이의 정수
- str.charCodeAt( idx: Number )
- A-Z는 65~90, a-z는 97~122번이며 소문자 → 대문자는 -32를 해주면 된다
const sentence = 'this is ahri';
sentence.charCodeAt(3) // 115 (i의 UTF-16코드값은 115)
const string = 'H';
string.charCodeAt() // 72
3.16 String.prototype.fromCode
- UTF-16코드를 문자열로 변환해 반환한다
- String.fromCharCode( num: Number | Number[] );
- 바로 위에서 본 charCodeAt을 문자열로 다시 반환할 때 써먹을 수 있음
const string = 'H';
const utf16 = string.charCodeAt() // 72
utf16.fromCharCode() // 'H'
// 표현하기 힘든 문자열도 생성 가능
String.fromCharCode(189, 43, 190, 61); // "½+¾="