이 목록에는 예약어에 꼭 포함할 것 같은 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
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을 쓰라는 것은 다음과 같은 이유입니다.
- 코딩할때 교과서적인 권장사항에서 if문의 비교에서 리터럴을 왼쪽에 쓰라는 것이 있습니다. (index == 3) 대신에 (3 == index)로 쓰라는 것이지요.(알지만 잘 안되는 것중 하나입니다.) 이 것은 실수로 ==를 =로 했을때 후자로 작성하면 Syntax오류가 나타나고 전자는 무조건 True로 떨어지지 때문입니다. 이 권장사항을 따랐을때 (undefined == index) 라고 작성하였을 때 실수로 ==대신 =를 작성한다면 undefined의 값을 변경해 버리는 실수를 해버릴 여지가 있다는 것입니다.(고의로 undefined를 재정의할 가능성보다는 이 경우가 훨씬 가능성 있어보이는군요.)
- 자신이 보기엔 null이 더 논리적으로 보이고 undefined가 수행하는 것을 모두 수행할수 있답니다.
- Function의 파라미터가 넘어왔는지를 검사할 용도에서는 undefined를 넘길 수도 있기 때문에 파라미터 검사용도로 undefined를 사용하는 것은 좋지 않습니다.
그래도 그냥 생각해도 그렇듯이 흔치는 않은 경우로 생각되므로 크리티컬한 이슈가 안되었는지 검색해도 많은 내용은 나오지 않았습니다. 대부분의 경우에는 undefined의 사용으로 문제가 없다고 봐도 무방하긴 하지만 알면서도 같은 결과라면 null비교를 사용하는 것이 더 나아보이는군요.
ECMAScript 스펙에서는 Infinity, NaN, undefined가 global object의 property로 분류되어 있다고 하네요.
https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Properties
그리고 말씀하신 대로 두 번째 예제에서는 undefined라는 '변수'에 값이 할당됐기 때문에 실행됐겠고, 전역변수로 undefined를 재정의하면 재앙이 닥치겠군요... ^^
예 스펙에 writable false라고 되어 있는데 의미가 좀 다른건지 재정의가 되더군요. 흔치 않은 일이겠지만 발생하면 재앙이겠습니다. ㅎ
이러한 문제가 있군요. undefined를 지금까지 즐겨 사용했지만 저 역시도 위와 같은 문제는 경험해 보지 못했습니다. 상상만해도 끔찍하긴 하네요.
저도 종종 사용했는데 이게 문제가 된다는건 첨보는 거라 크게 신경안써도 될듯하면서도 만약에라도 발생하면 진짜 끔찍할 듯 합니다.
이런 특이함(?)이 JS의 매력인지도 모르겠습니다.ㅎㅎㅎ
오호~~~~~~~~ 다시찾은 여유? ㅎ
밀린 포스팅거리들 처리하는 중이지.. ㅎㅎㅎ