1. 기본값과 래퍼객체

기본값

기본형, 기본자료형, 기본값 등으로 불리는데 영어로는 primative 라고 한다. 이하 기본값

자바스크립트에서 기본값이란 참조되지 않고 복제되며, immutable 한 자료형 이다. 이에 해당되는 것으로는 string, number, boolean, undefined, null, NaN 등이 있다 (null, undefined 는 객체 아니었어..?) 많은 브라우저가 undefined, null 을 객체로 만들어 참조가 되도록 잘못 설계한 오류가 있다. 따라서 아래와 같은 말도 안되는 상황이 벌어진다.

undefined = 3
if (undefined === 3 ) alert("zzz"); // 이게 실행됨

어쨋든 위에 열거한 자료형을 사용하면 참조되지 않고 복제되며 복제불가능하게 되는 것이 된다.. 하지만 각 기본값은 대응되는 객체 래퍼클래스가 존재한다. 만약 이를 이용하여 생성한 경우는 객체가 되기 때문에 복제가 아닌 참조로 작동학게 된다.

var a = "test"    // 기본값으로 작동!
alert( typeof a ) // string

var b = new String("test"); // 참조값으로 작동
alert( typeof b ) //objectt

사실 String 객체의 많은 메서드는 대부분 새로운 문자열을 return하기 때문에 b 를 함수의 인자로 보낸다고 해도, b자체가 변경될 가능성은 매우 희박하지만 문자열로 사용시 toString 을 추가로 호출해야하는 오버헤드가 발생한다.

래퍼객체

그렇다면 왜 이런 불편한 래퍼 객체가 존재하는 걸까? 누구나 예상 가능한 답변인, 객체로서 다양한 메서드를 사용할 수 있기 때문입니다. 아래는 String 의 래퍼로 만든 객체로 charAt메서드를 사용하는 예시다.

var a = new String("test");
alert( a.charAt(0) ); // t
alert( a.length );    // 4

그런데.... 래퍼객체가 아니라도 == 기본값 형태에서도 메서드를 사용할 수 있다!!

var a = "test";
alert( a.charAt(0) ); // t

이게 도대체 어떻게 된 일인가 보면... 대부분의 언어가 지원하는 박싱 이라는 기능이다. 우리가 모르는 사이에 아래와 같은 동작이 수행되고 있던것!!

var a= "test";
 
temp = new String( a );	// 임시 객체가 만들어진다!
alert( temp.charAt(0) );
temp = null;

박싱은 개발자가 사용하기 편하라고 만들어진 매크로 기능이다.

개발자가 래퍼객체를 사용하면 코드를 완전히 통제할 수 있게 된다. 하지만 기본값을 사용하고 이후의 작업은 C언어로 개발된 인터프리터가 하기 때문에 개발시간을 생각한다면 박싱이 빠르다고 할 수 있을것임.

만 박싱할 때 마다 임시객체가 만들어지는 것은 엄연한 사실이다. 따라서 아래처럼 사용한다면 우리가 보기에는 좋아보일지 몰라도, 내부 사정은 정말 끔찍할 것이다.

// 개발자의 시선
var a = "test";
 
var b = a.length + ":" +
a.charAt(0) + ":" +
a.charAt(1) + ":" +
a.charAt(2) +":"+
a.char(3);

// 내부의 사정
var a = "test";
 
t1 = new String( a );
t2 = new String( a );
t3 = new String( a );
t4 = new String( a );
t5 = new String( a );
 
var b = t1.length + ":" +
t2.charAt(0) + ":" +
t3.charAt(1) + ":" +
t4.charAt(2) +":"+
t5.char(3);
 
t1 = null;
t2 = null;
t3 = null;
t4 = null;
t5 = null;

기본값을 사용하는게(== 박싱문법을 사용하는게) 개발상 더 빨라 보일 수는 있지만 임시 객체를 만들어서 가비지 컬렉팅의 부하를 늘리는 문제점이 있다. 특히 브라우저의 구현에 따라서 임시 객체를 바로 delete 하지 않고 위처럼 null 로 처리하면 과도한 가비지컬렉팅 부하에 걸리기도 한다.

따라서 래퍼 메소드 사용 빈도에 따라 직접 래퍼객체를 생성하는 편이 유리한 경우도 많다.

var a = new String("test");
var b = a.length + ":" +
a.charAt(0) + ":" +
a.charAt(1) + ":" +
a.charAt(2) +":"+
a.char(3);
a = null;

이렇게 되면 객체를 직접 관리해야한다는 문제가 생긴다.

ECMA표준은 모든 메서드를 정적으로 쓸 수 있게 규정하고 있지만, 실제 구현여부는 브라우저마다 차이가 심하다.

Last updated