원시값의 메서드 (Methods of Primitive)
원시값 (Primitive)이란?
Javascript에서 말하는 원시값(Primitive)이란 무얼 뜻하는 것일까? 아래는 MDN에서 정의한 원시 값의 뜻이다.
원시 값(primitive, 또는 원시 자료형)이란 객체가 아니면서 메서드도 가지지 않는 데이터 입니다.
자바스크립트의 원시 값은 객체가 아니지만, 마치 객체처럼 다룰 수 있다. 원시값에도 객체에서처럼 메서드를 호출할 수 있다. 이와 관련해서는 아래에서 조금 더 깊게 알아보도록하자. 다만 원시값은 객체가 아니라는 점은 꼭 기억해야 한다.
원시값 vs 객체
원시값과 객체는 아래와 같은 차이점을 가지고 있다.
- 원시값
원시형 값으로, 총 일곱가지 종류가 있다.
문자(string), 숫자(number), bigint, 불린(boolean), 심볼(symbol), null, undefined - 객체
Property에 다양한 종류의 값을 지정할 수 있다.
{} 대괄호를 사용해 만들 수 있으며, 함수도 객체의 일종이다.
객체의 장점 중 하나는 함수를 Property로 저장하여 사용할 수 있다는 점이다. 아래 코드는 그 예시이다.
let soopiri = {
name: 'soopiri',
greating: () => {
console.log(`Hi~`)
}
}
soopiri.greating()
자바스크립트는 Date, Error, HTML등을 다룰 수 있게 해주는 다양한 내장 객체를 제공한다. 이 객체들은 고유한 Property와 메서드를 가진다. 다만 이런 기능들은 시스템 자원이 많이 소모된다는 단점이 있다. (사실 그렇게 많이 소모된다고 볼수도 없긴하지만 극한의 효율성을 추구한다면 그렇다). 객체는 원시값보다 무겁고, 내부 구조를 유지하기 위해 추가 자원을 사용한다.
원시값을 객체처럼?!
자바스크립트를 만든 브랜던 아이크(Brendan Eich)는 아래의 모순적 상황에 놓이게 된다.
- 원시값을 다뤄야하는 작업이 많은데, 메서드를 사용하면 작업을 수월하게 할 수 있을 것 같아!
- 그렇다고 해도 원시값은 최대한 빠르고 가벼워야 해
조금 어설프게 보일 수 있지만, 브랜든 아이크는 아래와 같은 방법을 통해 돌파구를 모색한다.
- 원시값은 원시값 그대로 남겨둬, 단일 값 형태를 유지하여 가볍고 빠르게 사용할 수 있도록 한다.
- string, number, boolean, symbol의 메서드와 프로퍼티에 접근할 수 있도록 언어 차원에서 허용한다.
- 이를 가능케 하기 위해, 원시값이 메서드나 프로퍼티에 접근하려면 "원시 래퍼 객체 (object wrapper)" 라는 특수한 객체를 만들어 주며, 접근 후 객체는 삭제되게 한다.
원시 래퍼 객체는 원시 타입에 따라 종류가 다양하며, 각 레퍼 객체는 원시 자료형의 이름과 최대한 비슷하도록 String, Number, Boolean, Symbol로 부른다. (앞이 대문자이다). 각 레퍼마다 제공하는 메서드 역시 다르다.
소수점을 원하는 자리에서 반올림 할 수 있는 숫자형의 고유 메서드 toFixed(n)를 예로 들어보자.
let num = 3.14159
console.log(num.toFixed(2)); // 3.14
위의 두 줄처럼 간단하게 사용할 수 있다. 아래는 num.toFixed(2)가 호출될 때 실제로 내부에서 일어나는 일련의 과정이다.
- 숫자 num은 원시값이므로, 원시값의 Property(toFixed)에 접근하는 순간 특별한 객체가 만들어 진다. 이 객체는 숫자의 값을 알고 있고, toFixed(n)와 같은 유용한 메서드를 가지고 있다.
- 메서드가 실행되고, 새로운 숫자가 반환된다.
- 특별한 객체는 제거되고, 원시값 num만 남게 된다.
이런 내부 프로세스를 통해 원시값을 가볍게 유지하면서도 메서드를 호출 할 수 있게 되는 것이다.
자바스크립트 엔진은 위에 설명한 Process의 최적화를 위해 많은 신경을 쓴다. 원시 래퍼 객체를 만들지 않고도 마치 원시 래퍼 객체를 생성한 것처럼 동작하게 해준다.
기타 주의사항
원시 래퍼 객체를 생성자로 사용하지는 말자.
C#, Java등의 몇몇 언어에서는 new String(), new Boolean(true) 등과 같은 문법을 사용해 원하는 타입의 래퍼 객체를 직접 만들 수 있다. 자바스크립트에서도 하위 호환성을 위해 이 기능을 남겨두었지만, 이런 식으로 래퍼 객체를 만드는 것을 추천하지 않는다. 다양한 상황에서 혼란스러워 질 수 있기 때문이다. 아래는 그 예시이다.
let zero = new Number(0);
console.log(typeof 0) // number
console.log(typeof zero) // object
// 객체는 논리 평가 시, 항상 true를 반환하기 때문에 아래 예시는 log를 찍게 된다.
if (zero) {
console.write('0이 언제부터 true였지?')
}
null과 undefined는 메서드가 없다.
특수 자료형인 null과 undefined의 원시값은 위의 법칙을 따르지 않는다. 이 원시값과 관련된 래퍼 객체도 없고 그렇기 때문에 당연히 메서드도 제공되지 않는다.
마무리
원시값에도 메서드는 존재한다.
null과 undefined를 제외한 원시값에서 다양한 메서드를 호출할 수 있다.
원시값의 메서드를 호출하려면 임시 객체가 만들어지지만, 자바스크립트 엔진의 최적화 덕분에 메서드를 호출해도 많은 리소스를 사용하지 않는다.
참고자료
'Development > JavaScript' 카테고리의 다른 글
defer와 async란? (0) | 2022.05.11 |
---|---|
Javascript - Set을 알아보자 (0) | 2022.04.27 |
Javascript - 맵(Map)을 알아보자 (0) | 2022.04.27 |
구조 분해 할당(Destructuring Assignment) - 객체, 중첩구조 편 (0) | 2022.04.26 |
구조 분해 할당(Destructuring Assignment) - 배열편 (0) | 2022.04.25 |