래퍼 객체

1. 배열

래퍼 객체에 대해 이해하기 전에 배열에 대해서 간단히 이야기하도록 하자.

배열은 어떻게 만들 수 있을까?
배열을 만드는 방법은 배열 리터럴 대괄호[]를 사용하는 방법Array() 생성자 함수로 배열을 생성하는 방법 이 있다.
예제를 통해 살펴보자.

1. 배열 리터럴 대괄호[]를 사용하는 방법

1
2
3
4
5
6
// 배열 생성
var arr = ['abcde'];

for (var i = 0; i < arr.length; i++) {
console.log(arr[i]);
}

Array() 생성자 함수로 배열을 생성하는 방법

1
2
3
4
5
6
// 배열 생성
var arr = new Array('abced');

for (var i = 0; i < arr.length; i++) {
console.log(arr[i]);
}

배열 리터럴을 사용하는 방법이 더 간략하므로 생성자 함수를 필수로 사용해야 하는게 아니라면 배열 리터럴을 사용하는 것이 더 좋다.

1.1 배열 길이 구하기

배열 내의 요소에 접근하는 여러 가지 방법이 있다.
그 중에서 배열 길이를 구하는 방법을 살펴보자.

1
var arr = [1,2,3,4,5];

위 예제와 같은 배열이 있다고 가정해보자. 이 배열의 길이를 구하려면 어떻게 해야할까?
이때는 length 프로퍼티를 사용하면 된다.

1
2
3
var arr = [1,2,3,4,5];

console.log(arr.length); // 5

그런데, arr.length 라는 표현식을 뜯어보자.
여기서 .은 뭐라고 할까? 이는 프로퍼티 참조 연산자라고 한다. 그렇다면 이 . 앞에는 뭐가 와야 할까?

이 점 앞에는 객체를 가리키는 식별자 가 와야 하고, 점 뒤에는 프로퍼티 이름 이 나와야 한다.

그렇다면 이 예제를 살펴보자.

1
2
3
var str = 'abcde';

console.log(str.length); // ??

이 예제를 실행하면 결과값은 5가 나온다. 여기서 이상한 점이 발견된다.

바로 앞의 예제에서 arr.length의 점 앞에는 객체를 가리키는 식별자 가 와야한다고 했는데 여기서 str이 객체일까?

str은 문자열 타입으로 원시 타입이다. 어떻게 이게 가능한걸까? 이를 알기 위해서는 래퍼 객체를 알아야 한다.

래퍼 객체에 대해서 알아보도록 하자.

  • 참고사항

중요한 내용은 아니지만 여기서 궁금한 점이 있다.
프로퍼티는 식별자일까 아닐까?
프로퍼티는 식별자가 아니다.
왜냐하면,

  1. 식별자 네이밍 규칙을 따르지 않아도 된다.
  2. 식별자를 찾을때, 실행 컨텍스트 안의 렉시컬 환경 안에 있는 환경 레코드에서 찾는다. 그런데, 프로퍼티는 프로토타입에서 찾는다.

따라서 프로퍼티는 식별자가 아니다. 알아두도록 하자.

래퍼 객체

래퍼 객체란 이름처럼 원시 타입의 값을 감싸는 형태의 객체이다. number, string, boolean, symbol 데이터 타입에 각각 대응하는 Number, String, Boolean, Symbol이 제공된다.

자바스크립트의 문자열은 원시 타입으로 존재한다. 우리가 문자열의 프로퍼티에 접근하려고 할 때(위의 str.length 예제처럼) 자바스크립트는 new String을 호출한 것처럼 문자열 값을 객체로 변환한다.
이 객체를 래퍼 객체라고 한다. 래퍼 객체는 프로퍼티를 참조할 때 생성되며 프로퍼티 참조가 끝나면 사라진다.

이러한 현상을 예제를 통해 살펴보자.

1
2
3
4
var str = 'abcde';
str.len = 5; // new String(str).len = 5

console.log(str.len); // undefined

두 번째 줄에서 s.len의 값으로 5를 할당했다. 하지만 다시 꺼내었을 때 출력되는 건 undefined이다. 두 번째 줄에서 str은 new String(str)로 바뀌었고 console.log(str.len)과는 다른 객체를 참조하고 있기 때문이다.

숫자와 불리언 타입도 문자열과 같은 방식으로 작동한다.

1
2
3
4
5
6
7
8
9
10
11
var num = 123;
typeof num; // "number"
num.toExponential();
num.prop = 1;
console.log(num.prop); // 'undefined'

var boo = true;
typeof boo; // "boolean"
boo.toString()
boo.name = 'abc';
console.log(boo.name); // 'undefined'

변수의 프로퍼티에 접근할 때 래퍼 객체가 임시로 생성된다. 프로퍼티의 값을 할당하는 것은 임시로 생성된 래퍼 객체에서 수행되며 지속되지 않는다. 이 때문에 원시 타입의 프로퍼티(실제로는 래퍼 객체의 프로퍼티)가 마치 읽기 전용 값처럼 존재하는 것이다.

원시 타입과 래퍼 객체는 거의 동등한 값처럼 다뤄진다. 동등 연산자 ==로는 이 둘을 구분할 수 없지만 엄격한 동등 연산자===로 구분할 수 있다.

1
2
3
4
5
var n  = 1;
var N = new Number(n);

console.log(n == N); // true
console.log(n === N); // false

Reference