비록 현재 왕성한 액션 히어로의 역할로 웹의 커다란 한 부분을 담당하고 있는 JavaScript라도 그 결점은 있기 마련이고, 언젠가는 이러한 언어 설계상의 오류가 자기의 뒤통수를 때릴 때가 있을 것이다. 결국, 미리 알아서 조심해야지.
JavaScript에서 NaN
값은 not a number라는 뜻으로, 즉 숫자가 아니라는 의미이다. 하지만,
typeof NaN === 'number' // true
이렇듯, typeof
로는 NaN
와 숫자를 구분할 수가 없거니와, 자신과의 비교도 불허한다.
NaN === NaN // falseNaN !== NaN // true
결국, JavaScript에서는 숫자와 NaN
를 구분하는 isNaN
라는 함수를 제공하고 있다:
isNaNNaN // trueisNaN0 // falseisNaN'oops' // trueisNaN'0' // false
결국, 숫자를 구별하는 가장 확실한 방법으로 다음과 같은 함수가 쓰일 수 있겠다:
return typeof value === 'number' && isFinitevalue;
typeof
얘기가 나와서 그러는데,
typeof null // object
null
대신에 object
를 돌려받는다. 그래서, null
값을 알아보기 위한 가장 좋은 방법은 아래와 같다:
my_value === null
또한, JavaScript의 Reserved Words는 보통 변수 이름으로 사용될 수 없는데, 굳이 reserved words를 object literals의 키 값으로 사용하려 할 경우에는, 항상 따옴표도 함께 써줘야 하고 dot notation 대신에 bracket notation을 사용해야 한다:
var method; // okvar class; // illegalobject = box: value; // okobject = case: value; // illegalobject = 'case': value; // okobjectbox = value; // okobjectcase = value; // illegalobject'case' = value; // ok
JavaScript는 프로그램 상 오류를 자동 수정하려는 성질이 있어서 문단 마지막에 항상 semicolons을 삽입하는데, 이것이 오히려 아래처럼 뜻하지 않는 문제를 일으킬 수도 있다.
returnstatus: true;
return 뒤에 바로 semicolon이 붙어버리면서 결국, undefined
값을 돌려주게 된다. 그래서 {
는 항상 아래처럼 앞 줄의 맨 마지막에 붙여주는 스타일을 손에 익혀야 한다.
returnstatus: true;
그리고 string을 integer로 바꾸어주는 parseInt
함수를 사용할 때는 항상 radix 매개 변수를 사용하는 버릇을 들여서, 아래와 같이 뜻하지 않는 결과를 초래하는 일을 미연에 방지한다.
parseInt"08"; // 0parseInt"09"; // 0parseInt"08" 10; // 8
또 하나, JavaScript의 소수점 계산은 형편없는 것으로 악명높다:
alert0.1 + 0.2; // 0.30000000000000004
이것은 JavaScript만의 문제가 아니라, Binary Floating-Point Arithmetic(IEEE 754)을 채용한 언어들에서 공통적으로 나타나는 문제점으로, ECMAScript 4에서는 Real Decimals의 채용하면서 이를 극복할 수 있는 문제지만, 당분간은 미리 scaling 해서 이 문제를 피할 수 밖에.
다음은 JavaScript에서 사용되는 여러가지 “falsy” 값들이다:
0(Number), NaN(Number), ”(String), false(Boolean), null(Object), undefined(Undefined).
모두 “falsy” 값을 가지지만 번갈아 서로 혼용되서 사용될 수는 없어서, 예를 들어 null
값을 구하는데, undefined
를 대신 사용하면 잘 못된 결과를 얻게 된다. 이 얘기는 자동 타입 변환(type coercion)을 일으키는 ==
연산자 대신에 더 염격한 ===
연산자를 사용하라는 얘기와 맞닿아 있다.
이 외에도, 실수든 혹은 필요에 의해서든 상호 운용성을 떨어뜨리는 global variables의 남용 등, JavaScript 문법 검사기인 JSLint를 한번 돌려 본 사람이라면 많은 골칫거리를 떠안게 된다. 하지만, 대부분의 골 때리는 일들은 잘못된 습관에서 비롯되는 경우가 많으므로 평소에 많은 코드를 접하면서 좋은 습관을 들이도록 노력하는 것이 중요할 것이다.
“JavaScript의 이런 점이 뒤통수를 때리더라.”에 달린 5개의 댓글
http://blog.naver.com/perfectacle
로 일부 내용을 퍼갔는데 출처 남겼습니다.
삭제를 원하시면 말씀해주세요 ^^
[…] 자바스크립트 null, undefined, NaN 비교와 검출 […]
NaN의 정의에 따르면 NaN은 어떠한 객체와도 같지 않으니
number != number // number가 NaN이면 true.
이런 식으로 검증할 수도 있을 것 같습니다.
어차피 isNaN 함수가 제공되지 그걸 쓰면 되지만요. ㅋㅋ
덧붙이면, 두 개의 값이 같은 것인지 혹은 같은 object인지 알아볼 때 확실한 방법으로 ECMAScript 2015에선 Object.is() 매소드를 제공하고 있습니다.
Object.is(NaN, 0/0); // true
Object.is([], []); // false
coercion 걱정 없이 비교할 수 있어서, 앞으로 브라우저 지원 상황이 좋아지면 유용하게 쓰일 수 있을 겁니다.
아주 훌륭한 글 잘 읽었습니다. 고맙습니다.