Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.
RetroTech 팟캐스트 44BITS 팟캐스트

undefined는 Reserved Word가 아닙니다.

요즘 봄싹스터디에서 더글라스 크락포드의 자바스크립트 핵심가이드로 Javascript를 공부중에 있는데 2장의 명명규칙을 설명하던 중 예약어(Reserved Word)를 표시해준 아래에 아래와 같은 말이 써 있었습니다.

이 목록에는 예약어에 꼭 포함할 것 같은 undefined, NaN, Infinity 등은 없습니다.
이 3개가 Reserved Word가 아니라는군요. 스터디에서 여러가지 테스트를 좀 했었지만 궁금해서 좀 더 찾아봤습니다. 일단 가장 확실한 현재 Javascript의 스펙인 ECMA-262를 보았습니다. ECMA-262에는 Identifier로 사용될 수 없는 Reserved Word가  Keyword, Future Reserved Word, NullLiteral, BooleanLiteral 4가지 종류로 정의되어 있습니다. 아래가 그 목록입니다.

Keyword
break    case    catch    continue    debugger    default    delete    do    else    finaly    for    function    if    in    instanceof    new    return    switch    this    throw    try    typeof    var    void    while    with

Future Reserved Word
class    enum    extends    super    const    export    import implements    interface    let    package    private    protected    public    static    yield

NullLiteral
null

BooleanLiteral
true     false

정말 undefined, NaN, Infinity는 없군요.


if (undefined) {
    console.log("Can't you see this message?"); // don't print
}

민망한 소스입니다. ㅋㅋ 당연히 저 메시지는 찍히지 않습니다.


var undefined = true;
if (undefined) {
   console.log("Can't you see this message?"); // it's printed
}


이렇게 바꿔봤습니다. undefined라는 변수를 만들어서 true로 설정해 주었습니다. 당황스럽게도 이 메시지는 찍힙니다. ㅡ..ㅡ 간단한 테스트로는 FF3.6, Chrome 4, IE8에서 모두 동일한 결과가 나타납니다. undefined가 Reserved Word가 아닌 이유가 궁금할 정도로 당혹스러운 결과입니다. 이것은 temp == undefined 같은 비교가 소스에 있을 경우 전역변수로 undefined를 다른 값으로 정의해 버리면 전체 코드를 깨뜨려 버릴수 있다는 말과 동일합니다.

물론 undefined를 변수명으로 쓸 사람이 있겠냐 싶기는 합니다만 가능하기 때문에 꼭 없다고 할 수만도 없을 일이지요. 여러사람이 작성한 코드에서 누가 undefined를 재정의한다면 디버깅한다는게 정말 끔찍하네요. 좀 더 자세한 내용을 찾아보려고 검색해봤더니 해당 내용에 대해서 정확히 짚어낸 "undefined is not a reserved word"라는 글을 찾을 수 있었습니다. 위 블로그에서 Ash는 비교할때 undefined를 사용하지 말라고 권하고 있습니다. row == undefined같은 형태로 비교하지 말고 row == null로 비교할 것을 권하고 있으며 ==비교에서는 null과 undefined가 완전히 동일하게 취급하기 때문에 Reserved Word인 null을 권하고 있는 것입니다.(타입까지 비교하는 ===에서는 당연히 같지 않습니다.)

댓글을 통해서 Tim Down라는 사람과 위 문제에 대해서 좀 얘기가 있었는데 Ash가 null을 쓰라는 것은 다음과 같은 이유입니다.

  1. 코딩할때 교과서적인 권장사항에서 if문의 비교에서 리터럴을 왼쪽에 쓰라는 것이 있습니다. (index == 3) 대신에 (3 == index)로 쓰라는 것이지요.(알지만 잘 안되는 것중 하나입니다.) 이 것은 실수로 ==를 =로 했을때 후자로 작성하면 Syntax오류가 나타나고 전자는 무조건 True로 떨어지지 때문입니다. 이 권장사항을 따랐을때 (undefined == index) 라고 작성하였을 때 실수로 ==대신 =를 작성한다면 undefined의 값을 변경해 버리는 실수를 해버릴 여지가 있다는 것입니다.(고의로 undefined를 재정의할 가능성보다는 이 경우가 훨씬 가능성 있어보이는군요.)
  2. 자신이 보기엔 null이 더 논리적으로 보이고 undefined가 수행하는 것을 모두 수행할수 있답니다.
  3. Function의 파라미터가 넘어왔는지를 검사할 용도에서는 undefined를 넘길 수도 있기 때문에 파라미터 검사용도로 undefined를 사용하는 것은 좋지 않습니다.

그래도 그냥 생각해도 그렇듯이 흔치는 않은 경우로 생각되므로 크리티컬한 이슈가 안되었는지 검색해도 많은 내용은 나오지 않았습니다. 대부분의 경우에는 undefined의 사용으로 문제가 없다고 봐도 무방하긴 하지만 알면서도 같은 결과라면 null비교를 사용하는 것이 더 나아보이는군요.
2010/02/10 01:34 2010/02/10 01:34