태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.


* typeof와 instanceof는 어떠한 변수가 문자열인지아닌지, 특정한 객체인지 아닌지 판단할때 사용하는 '연산자'들이다. 이들 둘이 어떻게 다른지 살펴보고 사용하면서 있을 수 있는 약점들도 같이 살펴보자.


* typeof

: typeof는 unary 오퍼레이터이다. unary 오퍼레이터로는 ! 라던가 - 등과 같이 인자를 하나만 받을 수 있는 연산자를 뜻한다. 즉, 함수가 아니고 연산자이기 때문에 괄호를 사용하면 안된다.


typeof yourVariable;

위와 같이 실행하고 나면 리턴 값으로는 해당하는 변수의 primitive 타입을 스트링으로 준다. 돌려주는 primitive 타입의 종류는 아래와 같다.


  • 'undefined'
  • 'boolean'
  • 'number'
  • 'string'
  • 'object'
  • 'function'

위의 기본 형식 중 하나를 스트링 형태로 리턴하기 때문에 어떠한 형인지 스트링으로 구분을 하면 된다. 즉, typeof를 사용해서 object인지 아닌지를 판별하는 경우 아래와 같이 하면 된다.


if(typeof yourVariable === 'object') { /* 오브젝트 처리 */}

하지만 위와 같이 하게 되면 만약 yourVariable이 null이라면 결과가 true로 나타난다. 따라서 null인 경우 false의 결과를 나타내고 싶다면,

if(yourVariable != null && typeof yourVariable === 'object') {/*오브젝트 처리*/}
if(!!yourVariable && typeof yourVariable === 'object') {/*오브젝트 처리*/}

위의 방법둘 중 하나를 하면 된다. 변수가 string인 경우를 판별하고 싶다면 위의 'object'를 'string'으로 바꿔주면 된다. 간단한 예들을 들어보면,


typeof 3;    // === 'number'
typeof 'str';    // === 'string'
typeof {};    // === 'object'
typeof [];    // === 'object'
typeof function () {};    // === 'function'
typeof null; // === 'object'

위의 테스트를 구글 크롬에서 개발자 도구의 콘솔을 열어서 실행해보면 쉽게 직접 결과를 확인할 수 있을 것이다.


: 그럼 instanceof는 어떻게 다른지 살펴보자.



* instanceof

: instanceof 는 비교 연산자로 >,<,== 와 같이 두개의 인자를 받는 연산자로 앞의 비교 연산자들을 이용하는 기분으로 사용하면 된다. 하지만 결과로 리턴하는 것은 typeof와는 성질이 조금 다르다. instanceof는 해당하는 변수가 사용하고 있는 prototype의 chain을 2번째 인자와 쭉 비교해서 true/false 값을 리턴한다.


쉬운말로 하자면, 해당하는 변수의 클래스와 비교해서 리턴해주는, java에서 많이 쓰던것과 비슷하다고 볼 수 있다.


var Person = function(){
    this.name = "unikys";
};
var inst = new Person();

inst instanceof Person; // === true
inst instanceof Object; // === true
typeof inst; // === 'object'


instanceof는 클래스의 타입을 감지하는 역할을 하고, 위의 예를 통해 모든 클래스는 기본 클래스인 Object를 확장한다는 것을 알 수 있다.


: 하지만 자바스크립트라는 언어의 특징 때문에 그 동작하는 것은 부분부분 매우 다르기도 하다. instanceof가 동작을 다르게 한다기 보다는 자바스크립트라는 언어 자체가 다르게 동작을 하는 것으로 보면 된다. 가장 대표적인 예로 {}는 new Object()와 같은 의미를 하며, []는 new Array()와 같은 의미를 가지므로 위에 대해서 instanceof를 사용해보면 true가 나올 것이다. 하지만 다른 primitive type들에 대해서는 클래스로 instanceof를 할 수가 없다.


"foo" instanceof String; // === false
"foo" instanceof Object; // === false
true instanceof Boolean; // === false
true instanceof Object; // === false

[0,1] instanceof Array; // === true
{0:1} instanceof Object; // === true

var color1 = new String("red");
var color2 = "red";
color1 == color2; // === true
color1 instanceof String; // === true
color2 instanceof String; // === 무엇일까요?


위의 맨 아래 구분은 true/false 무엇일까? 왜 물어보는지 예상하셨다면 답은 false다. 다음과 같은 경우 자바스크립트를 처음 접해봤다면 이해를 할 수 없을 것이다. color1의 경우는 String이 맞지만 color2는 primitive type string으로 다르다. 하지만 비교 연산자 ==는 true가 나온다. 어떻게 보면 편하면서도 잘못사용하면 원인도 모르고 삽질을 할지도 모른다. 위에서 object literal인 []와 {}에 대해서 typeof는 둘다 object를 리턴했지만, instanceof는 각각 Array와 Object를 리턴한 것도 관심을 가져야할 결과이다. 아래는 그래서 조금 다른 예이다.


"foo".constructor instanceof String; // === false
"foo".constructor === String; // === true?!


이건 또 어떻게 된 영문인가? "foo".constructor는 String하고 같지만 String의 instance는 아니다?! 여기서 크롬의 개발자 콘솔에 String을 쳐보면 왜 그런지 알 수 있을 것이다.


String
function String() { [native code] }


크롬에서 String을 실행하면 위와같이 나온다. "foo".constructor 는 Function의 instance인 것이다. instance의 개념에 대해서 다시한번 돌이켜보면 어쩌면 당연한 결과이기도 하다. 즉, String 자체는 Function의 instance인 것이다.


* 이렇게 살펴보면 결국 두가지의 연산자는 각각 다른 용도로 활용하면 될 것이다. primitive type을 구분할 때에는 typeof를 사용하고 클래스의 타입을 구분할 때에는 instanceof를 사용하면 된다.


끝.


이 글을 공유하세요.

  • 궁금증 2012.11.15 10:54 신고  댓글주소  수정/삭제  댓글쓰기

    안녕하세요.

    저기 위에서 설명하는 object 형이 {}, []이라고 하셨는데 object형에 포함되는 건 어떤 걸 말하는건지 이해가 잘 안되네요 ㅎㅎ;;; 설명좀 부탁드릴게요.

    • Unikys 2012.11.15 16:07 신고  댓글주소  수정/삭제

      네~ 일단 'object'라 하면 기본형이 아닌 객체를 뜻하고, 다른 언어에서 말하는 '클래스'와 비슷하게 생각하시면 됩니다.
      자바스크립트에서는 {}와 []가 독특한 특징인데, 얘네를 object literal 그리고 array literal이라고 부르는데요, 얘네들이 object로 나오는 이유는 {}가 뜻하는 바는 new Object(); 와 같은 것을 뜻하지만 그것을 간단히 표현한 것이고, []는 new Array();를 간단하게 표현한것이라고 생각하시면 됩니다. new Object();는 기본형이 아닌 객체이므로 object형이 되는 것입니다.
      즉, typeof {}와 typeof [] === 'object'으로 되는 것이고, instanceof를 해보면 var a = {}; a instanceof Object === true; var b = []; b instanceof Array === true; 이렇게 됩니다. 이해 안되시는 부분 있으시면 또 질문해주세요^^

  • 감사합니다 2013.01.09 16:37 신고  댓글주소  수정/삭제  댓글쓰기

    안녕하세요. 포스트글들 감사하게 잘 보고있습니다.

    위 포스트를 보다가 궁금증이 생겨서요.

    위의 if(!!yourVariable && typeof yourVariable === 'object') {/*오브젝트 처리*/} 문장에서 !를 두번 쓴것과 안쓴것의 차이는 어떻게 다른건가요?

    • Unikys 2013.01.09 17:38 신고  댓글주소  수정/삭제

      사실 위와 같이 아주 간단한 상황에서는 !!yourVariable을 쓰든, 그냥 yourVariable을 쓰든 상관없습니다. 물론 내부적인 하는 동작은 다릅니다만, 다른 경우에서 만약 다른 개발자와 협업을 할 때 저 변수가 boolean 값으로 의도된 것이 아니라 변수의 선언(할당)여부를 판단하는건지 알려주는 일종의 신호이기도 하고요, 저는 그냥 습관적으로 이 if 안에는 반드시 boolean을 쓰자는 생각으로 boolean으로 변환한 것입니다.
      위의 예가 아니라 다른 예에서 조금 다른 내부적인 이유가 있다면, 위처럼 && 연산자인 경우는 어짜피 마지막 피연산자의 값을 short circuit으로 가져가므로 해당 yourVariable은 Boolean으로 형변환을 한번하니까 굳이 !!를 안 써도 되지만, 만약 다른 예에서 if 안에 ||가 있는 경우라면 || 연산을 할때 형변환 한번, if에서 다시 한번 이렇게 2번은 형변환하게 되므로 !!를 사용하는 것이 조금 더 유리하겠지요. 물론 이런 작은 차이들은 피부로는 크게 와닿을만한 사항이 아니라서 크게 신경쓰시면서 코딩할 필요는 없을 것 같습니다^^;

  • alpaca 2018.09.13 17:02 신고  댓글주소  수정/삭제  댓글쓰기

    감사합니다 공부하는데 많은 도움 되었습니다!

질문이나 의견을 댓글로 달아 주세요