자바스크립트를 작성하다 보면, 객체와 배열을 구분해야할 때가 있다.
근데 타입을 조사하는 함수인 typeof 를 실행해 보면 객체와 배열 모두 ‘object’를 반환한다.

1
2
console.log(typeof {});//"object"
console.log(typeof []);//"object"

이때 사용하는 방법은, 자바스크립트 객체의 메소드인 toString을 활용하는 것이다.
일단 소스는 아래와 같다.

위의 예제에서 typeof 대신 toString을 실행해보면 아래와 같이 나온다.

1
2
console.log(Object.prototype.toString.call({}))//;"[object Object]"
console.log(Object.prototype.toString.call([]));//"[object Array]"

위 예제에서 특이한 것은 toString메소드를 해당 객체(또는 배열)에 직접 실행 한 것이 아니라 Object객체의 프로토타입 프로퍼티로 실행을 시키고 call이라는 재귀 함수를 통해 toString을 해당 객체(또는 배열)의 메소드화 시켰다는 것이다.

일반적으로 우리가 사용하는 방법인 [].toString()과 이 방법의 차이는 무엇인가..?(이 방법으로 하면 배열을 콤마(,)로 구분된 문자열을 반환한다)

[].toString()의 toString은 배열([])의 프로토타입인 Array 객체로 부터 상속받아 사용하는 메소드이고,
Object.prototype.toString.call([])의 toString은 배열([])에 Object의 메소드인 toString()을 직접 정의시킨 메소드 인 것이다.

즉 Array객체의 toString을 사용하면 우리가 원하는 객체 타입을 반환하는 것이 아니라 배열을 문자열로 반환시켜 버리므로, Object객체의 toString을 사용하도록 강제로 설정했다고 볼 수 있다.

자 그럼 이제 객체의 class를 구분하는 함수를 만들어 보면..

1
2
3
4
5
6
7
8
function getClassType(obj){
return Object.prototype.toString.call(obj).slice(8,-1);
}
console.log(getClassType([]));//"Array"
console.log(getClassType({}));//"Object"
console.log(getClassType(1));//"Number"
console.log(getClassType(new Date()));//"Date"

이처럼 반환된 문자열을 slice 메소드를 통해 잘라내어 class를 구할 수 있다.^^