javascript에서 다음과 같은 메소드를 사용한 경험이 있을 것이다.
// 대문자로 변경
const greeting = "hello world!";
greeting.toUpperCase();
// 소수점 표현
const num = 1.4435;
num.toFixed(1);
"hello world!"
와 1.4435
는 Primitive 타입이다. 즉, 객체가 아니기에 가지고 있는 메소드가 없다. 하지만 메소드를 사용할 수 있는 이유가 바로 Boxing 과정이 이루어지기 때문이다.
Primitive 타입을 wrapper 객체로 wrapping하는 과정을 말한다. greeting변수를 기준으로 설명하고자 한다.
우선 greeting.toUpperCase()
를 실행하게 되면 javascript에서 greeting의 Primitive타입의 Reference타입인 String 객체로 암묵적으로 변환 시킨다. 그리고 String의 prototype 체이닝을 타고 toUpperCase()
메소드를 찾아 실행하게 된다. num 변수도 같은 과정이 일어나서 toFixed(1)
를 실행할 수 있게 된다.
주로 명시적으로 하기보다 암묵적인 boxing과정을 이용한다.
반대로 Reference타입의 객체의 Primitive 값을 얻는 과정을 말한다. valueOf()
메소드를 이용해서 unboxing을 할 수 있다.
const flag = new Boolean(false);
const flag2 = false;
if(flag === flag2) {
console.log('성공');
} else {
console.log('실패');
}
// 실패
console.log(typeof flag); // object
console.log(typeof flag2); // boolean
위 과정에서 ===
를 사용하여 비교하게 되면 둘은 같지 않게 나온다. 둘의 타입이 다르기 때문이다. 하지만 valueof()
를 통해 unboxing을 한다면 unboxing된 값은 Primitive 타입이기에 비교가 성공하게 된다.
const flag = new Boolean(false);
const flag2 = false;
if(flag.valueOf() === flag2) {
console.log('성공');
} else {
console.log('실패');
}
// 성공
추가적으로 조금 이해가 필요한 부분이 있는데 다음의 예시를 보자
console.log(flag === flag2); // false
console.log(flag == flag2); // true
==
연산에서는 왜 true
가 나올까? 타입 비교가 아닌 값의 비교이고 이 때 내부 슬롯 [[PrimitiveValue]]
를 이용하여 비교하게 된다.