티스토리 뷰

원래 발표 자료는 총 15장이 었는데, 예제 코드와 설명이 필요한 것은 이번으로 마무리 하려고 한다.

implicit type conversion

자바스크립트는 약한 타입(weak typing) 이므로, 묵시적인 형변환(implicit type conversion)이 빈번하게 이루어진다. 이로 인한 부작용을 간과하면 찾기 어려운 버그를 만들 수 있다.

간단한 예를 통해 알아보자:
function test(foo) {
  alert(typeof(foo));
  alert(foo);
  if (foo) { alert('foo'); }
  if (foo == null) { alert('foo == null'); }
  if (foo === null) { alert('foo === null'); }
}

이 함수를 여러가지 파라메터를 주면서 호출해보자.
test();
test(null);
test('hello');
test('');
test(true);
test(false);
test(1);
test(1/0);
test(0/0);

특이한 것 몇가지만 얘기하면:
  • underfined는 == null 이지만 === null 은 아니다.
  • ''는 false다! (C에서는 !=0 이면 모두 true라는 사실을 기억하라)
  • 1/0(불능)은 true지만, 0/0(부정)은 false다!

묵시적 형변환과 관련된 또 다른 예를 살펴보자:
function test(foo) {
  alert(typeof(foo));
  alert(foo);
  if (foo) { alert('foo'); }
  if (!foo) { alert('!foo'); }
  if (!!foo) { alert('!!foo'); }
}

파라메터가 명확한 불린 값이라면(true/false) 아무런 문제가 없지만, 그렇지 못하면 예상치 못한 상황에 직면하게 된다:
test(true);
test(false);
test('true');
test('false');

특이한 것은:
  • !!'false'는 false가 아니라 true다.

weak typing은 아주 편리한 언어적 특성이지만, 잘못쓰면 - 특히 strong typing(C, 자바 등의 대부분의 주류 언어)에 익숙한 개발자들에게 - 치명적인 독이 될 수 있다. underfined, null, NaN 그리고 ""(빈문자열) 간의 차이는 상당히 오묘하므로, 가장 확실한 방법은 확신이 없다면 명시적인 형변환을 수행하는 것이다.

nested block scope

function test() {
  var foo = -1;
  for (var foo = 0; foo < 10; foo++) { … }
  alert(foo);
}

위의 코드에서 두번째 var 선언문은 아무 효과가 없다. 따라서, -1이 아니라 10이 출력된다. 별것 아닌것 처럼 보이지만, 문제가 되면 굉장히 찾기 어려운 버그다. jslint를 사용하면 경고를 해주는 데, 가장 확실한 방법은 모든 변수 선언을 함수 앞에 모아두는 것이다(예전 C 스타일).
 
function overloading

function test(foo) {
  alert('one arg');
}
function test(foo, bar) {
  alert('two args');
}
function test() {
  for (var i = 0; i < arguments.length; i++) {
    alert(arguments[i]);
  }
}

위의 코드에서 앞에 두개의 함수 정의는 무시되고, 마지막의 세번째 함수 정의만 유효하다. 자바스크립트에서는 arguments를 사용하여 가변 파라메터를 처리할 수 있다. 그러나, 더 좋은 방법은 이름있는 파라메터를 사용하는 것이다. 즉, 객체 하나에 파라메터의 이름과 값을 함께 전달 하는 것인데, 요즘 많이 쓰이는 대부분의 자바스크립트 라이브러리들이 모두 이 방식을 선호한다.

"string" is not array-of-chars

var str = "hello";
alert(str.charAt(2));
alert(str[2]);

위의 코드에서 앞의 alert은 출력되지만, 뒤의 alert은 에러다. 잘된다고? IE에서는 해보시길...
자바 개발자들에겐 익숙할텐데, C/C++ 개발자들은 좀 귀찮을 듯... ^^;

비슷한 예로, NodeList(예: document.getElementsByName() 등의 리턴 형식)도 배열이 아니다.

missing "radix" for  parseInt()

parseInt('1234');
parseInt('01234');
parseInt('0x1234');
parseInt('1234', 10); 
parseInt('1234', 8);
parseInt('1234', 16);

뭐가 이상하냐고? 자바에서 똑같은 짓을 해보자. -.-;;;; 자바에선 Integer.parseInt()에 radix를 지정하지 않으면 10을 지정한 것으로 처리하지만, 자바스크립트에선 알아서 하라는 뜻으로 해석한다.

var sum = parseInt(num1.value) + parseInt(num2.value);
alert(sum);

위의 코드는 의도했던 안했던, 8진수와 16진수 계산기 기능도 갖고 있다. ^^; 이런 사소한 문제가 찾아내기 힘든 버그를 만든다. jslint를 사용하면 경고를 해주는데, 가장 확실한 방법은 parseInt()를 호출할 때 무조건 두번째 파라메터(radix)를 지정하는 것이다. 

이것으로 JavaScript Common Mistakes 시리즈도 끝~
그 시작은 창대하였으나 끝은 미미하리라...=3=3=333

아.. 쪽팔려...

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/03   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
글 보관함