모던 JavaScript 튜토리얼을 따라가면서 정리합니다.
5.1. 원시값의 메서드
문자열이나 숫자 같은 원시값을 다루어야 하는 작업이 많은데, 메서드를 활용하면 작업을 수월하게 할 수 있을 것이다. 그러나 원시값은 가능한 한 빠르고 가벼워야 한다.
자바스크립트는 원시값(문자열, 숫자 등)을 마치 객체처럼 다룰 수 있게 해준다. ‘null’과 ‘undefined’를 제외한 원시값에 다양한 메서드를 호출할 수 있다. 그런데 자바스크립트 엔진은 내부 최적화가 잘 되어있어 메서드를 호출해도 많은 리소스를 쓰지 않는다.
방법
- 원시값은 원시값 그대로 남겨둬 단일 값 형태를 유지한다.
- 문자열, 숫자, 불린, 심볼의 메서드와 프로퍼티에 접근할 수 있도록 언엉 차원에서 허용한다.
- 이를 가능하게 하기 위해, 원시값이 메서드나 프로퍼티에 접근하려 하면 추가 기능을 제공해주는 특수한 객체 “원시 래퍼 객체(object wrapper)”를 만들어준다. 이 객체는 곧 삭제된다.
래퍼 객체는 원시 자료형의 이름을 그대로 차용해
String
,Number
,Boolean
,Symbol
이라고 부른다. 래퍼 객체마다 제공하는 메서드 역시 다르다.예시:
1 2
let str = "Hello"; alert( str.toUpperCase() ); // HELLO
- 문자열
str
은 원시값이므로 원시값의 프로퍼티(toUpperCase
)에 접근하는 순간 특별한 객체가 만들어진다. 이 객체는 문자열의 값을 알고 있고,toUpperCase()
와 같은 유용한 메서드를 갖고 있다. - 메서드가 실행되고, 새로운 문자열이 반환된다(
alert
창에 이 문자열이 출력된다.) - 특별한 객체는 파괴되고, 원시값
str
만 남는다.
- 문자열
String/Number/Boolean
을 생성자로 사용하면 혼동이 일어나므로 지양하자.1 2
alert (typeof 0); // "number" alert (typeof new Number(0)); // "object"
1 2 3 4 5
let zero = new Number(0); if (zero) { alert("zero는 객체이므로 조건문이 참이 된다."); }
new
없이 사용하면 괜찮다.null/undefined
는 래퍼 객체도, 메서드도 제공하지 않는다. 이런 면에서 “가장 원시적”이라고도 할 수 있다.
과제
문자열에 프로퍼티를 추가할 수 있을까?
1
2
3
let str = "Hello";
str.test = 5; (*)
alert(str.test);
비 엄격모드이면 undefined
가 출력되고, 엄격모드이면 에러가 발생한다.
str
의 프로퍼티에 접근하려 하면 래퍼 객체가 만들어진다.- 엄격 모드에서는 래퍼 객체를 수정하려 할 때 에러가 발생한다.
- 비 엄격모드에서는 에러가 발생하지 않고 프로퍼티
test
가 추가된다. 그런데 래퍼 객체는 바로 삭제되기 때문에 마지막 줄이 실행될 땐 프로퍼티test
를 찾을 수 없다.
원시값은 객체와 달리, 추가 데이터를 저장할 수 없다!!!