래퍼 객체란?
래퍼객체는 이름 그대로, 감싸는 객체이다.
래퍼객체는 원시값과 관련되어 있다.
원시값에는 string, number, bigInt, boolean, Symbol, null, undefined로 7가지가 있다.
MDN에 의하면, 원시값의 정의는 객체가 아니면서 메서드도 가지지 않는 불변의 데이터이다.
메서드를 가지지 않는다면서..?
const str = 'capital letter';
console.log(str.toUpperCase());
그런데 실제로는 원시값을 담은 변수에서 메서드를 사용할 수 있었다.
이는 자바스크립트가 원시값에 래퍼객체를 이용해서 객체의 다재다능함을 부여하기 때문에 가능하다.
래퍼객체의 종류, 동작 순서
래퍼객체에는 String, Number, Boolean, Symbol이 있다.
래퍼객체는 원시값에서 메서드를 호출하면, 순간적으로 생성되어 메서드에 해당하는 로직을 수행하고 결과를 반환해준다.
const str = 'capital letter';
console.log(str.toUpperCase());
코드의 동작 순서는 다음과 같다.
1. str 변수에서 toUpperCase를 호출하는 순간 String 래퍼 객체가 생성된다.
2. 래퍼 객체가 str 값과, 자신의 메서드를 이용해 결과를 반환한다.
3. 결과반환을 마친 래퍼객체는 삭제된다.
위의 스텝은 자바스크립트 엔진이 수행해주며, 이 덕분에 원시값의 성질을 유지하면서도 메서드 이용이 가능하다.
조금 TMI를 덧붙여 string, number 타입의 메서드 호출을 예로 들면,
래퍼 객체가 생성되면 래퍼객체의 [[StringData]] 혹은 [[NumberData]] 슬롯에 원시값을 할당하고
래퍼 객체의 역할이 끝나면 해당 슬롯을 이용하여 다시 식별자가 원시값을 갖도록 되돌린다.
다시 식별자가 원시값을 갖도록 되돌려지므로, 래퍼 객체는 가비지컬렉션의 대상이 된다.
래퍼객체를 통한 메서드 이용 시 주의할 점으로는 원시값은 불변의 값이라는 것이다.
메서드를 호출했을 때 결과가 반환되지만, 변수의 값이 변경되지 않는다.
그러므로 항상 메서드의 수행 결과를 이용할 때는, 즉시 결과를 이용하지 않는다면 다른 변수에 저장해야 한다.
이와 관련해서, 착각하기 쉬운 케이스를 보자.
const str = '배가 고파요 생선님.';
str.replace('생선','선생'); // 다음의 결과로 '배가 고파요 선생님' 을 출력한다.
console.log(str); // 그러나 str 변수가 가리키는 원시값 자체는 변하지 않았다.
const modifiedStr = str.replace('생선', '선생'); // 결과를 변수에 넣어줘야 한다.
console.log(modifiedStr);
생성자를 통해 래퍼객체를 생성할까?
생성자를 통한 래퍼객체 생성을 허용한 것은 하위호환을 위한 일이다.
생성자(new 키워드)를 통해 직접 해당 타입의 래퍼객체를 선언해서, 원시값처럼 쓰는 것은 좋지 않다.
문자열로 선언한 숫자값 f를 new 키워드로 숫자화한다면, 타입이 객체가 되어버린다.
이는 타입 체크등의 로직에서 문제를 일으킬 수도 있고,
원시값에 비해 객체는 기능이 무거워서 자원을 많이 사용하므로 필요하지 않은 객체 선언을 지양해야 한다.
숫자->불린 / 문자->숫자로의 형변환을 원한다면?
new 키워드 없이 String/Number/Boolean 으로만 감싸주면 해당하는 원시값으로 형변환이 일어나게 할 수 있다.
혹은 자바스크립트의 자동 형변환을 이해하고, while(1), +'1234', '12'-'70' 등의 코드를 작성할 수도 있겠다.
'JavaScript > theory' 카테고리의 다른 글
객체 프로퍼티의 getter와 setter (0) | 2022.01.17 |
---|---|
객체 프로퍼티 플래그와 설명자(Flag & Descriptor) (0) | 2022.01.17 |
[자바스크립트] V8 엔진의 메모리 관리 이해하기 (0) | 2022.01.12 |
[자바스크립트] 일반 객체 다루기 (0) | 2022.01.11 |
[자바스크립트] 고차함수와 배열 내장 메서드 (0) | 2022.01.06 |