title

JavaScript에서 클래스를 사용할 때의 생성자

Tip&Tech | 2008.03.28 19:51

JavaScript에서는 function 객체를 클래스 타입이자 생성자로 사용할 수 있다. 다음은 간단한 예제 코드이다.

function typeClass() {
}
var oInstance = new typeClass;

인스턴스를 생성할 때 사용한 클래스 겸 생성자인 typeClass는 인스턴스 객체의 constructor 속성으로 접근할 수 있다. 이는 Array, Object 등을 비롯한 JavaScript의 코어 객체도 마찬가지다.

function typeClass() {};
var oInstance = new typeClass;
alert(oInstance.constructor == typeClass);

한편, 함수의 prototype 속성을 이용하면 상속도 가능하다. 이용해서 한꺼번에 메소드, 프로퍼티를 정의할 수도 있다. 유명한 프레임웍인 prototype.js 도 기본 원리는 다음의 코드와 비슷하게 구현이 되어있다.

function typeClass() {};
typeClass.prototype = {
  method : function(){}
};
var oInstance = new typeClass;

이제 아까와 마찬가지로 constructor 속성에 접근해보도록 하자.

function typeClass() {};
typeClass.prototype = {
  method : function(){}
};
var oInstance = new typeClass;
alert(oInstance.constructor == typeClass);


어째 결과가 이상하지 않은가? typeof 연산자로 체크해봐도 oInstance.constructor 는 “function”이 아닌 “object” 타입으로 출력된다. 확실한 원인은 모르겠으나 prototype이 재정의되면서 이러한 문제가 발생하는 것 같다. 아래 코드에서는 여전히 constructor 가 function 으로 출력되고, typeClass는 oInstance의 클래스 타입이다.
function typeClass() {};
typeClass.prototype.method = function(){};
var oInstance = new typeClass;
alert(oInstance.constructor == typeClass);

이 같은 문제를 다음과 같은 두 가지 방법으로 해결할 수 있다.

  1. typeClass.prototype 을 재정의하지 않고 각각의 프로퍼티나 메소드를 덧붙인다.
  2. typeClass의 prototype.constructor 를 재정의한다.
      1  function typeClass() {
      2  }
      3  typeClass.prototype = {
      4    method : function() {
      5    }
      6  }
      7  typeClass.prototype.constructor = typeClass;
      8  var oInstance = new typeClass;
      9  alert(oInstance.constructor == typeClass);
     10  };

추가 // prototype.js에는 이런 문제가 수정되어있습니다. 제가 보던 때와는 달리 많이 변경된 것 같습니다. ^^;;

[JS] JavaScript 코딩팁

Tip&Tech | 2008.02.27 18:34

그 동안 잘 써오던 팁인데 의외로 잘 안쓰시는 것 같아서 공유하고자 합니다. ^^

1. 문자열을 숫자로…

보통 이 경우에는 parseInt 메소드를 많이 이용합니다만, 언어의 특성을 이용한다면 간단히 해결할 수 있습니다.

var str = "100";

  • parseInt : parseInt(str) // 결과는 100
  • + : +str // 결과는 100, 단 앞에 아무런 값이나 변수가 없어야 함
  • - 0 : str-0 // 결과는 100

var str = "010";

  • parseInt : parseInt(str) // 결과는 8
  • + : +str // 결과는 10
  • - 0 : str-0 // 결과는 10

위 결과에서 str 앞에 0이 있기 때문에 parseInt 함수는 이를 8진수 10으로 해석하게 됩니다. 이 문제를 해결하려면 parseInt 의 두 번째 인자로 지수값 즉 여기서는 10을 넘겨주면 됩니다.

2. Boolean 값으로 타입 변환

JavaScript 에는 Bool 로 인정되는 몇몇 값들이 있습니다. 이들 값들은 if 문이나 삼항비교문에서도 역시 bool 값으로 인정됩니다만, 그렇다고 이들이 실제로 boolean 값인 것은 아니라서 boolean 값 자체가 필요할 때는 보통 다음과 같이 변환을 하시더군요.

var nVal = 2;
var bVal = nVal?true:false;

하지만 다음과 같은 방식으로 캐스팅을 한다면 보다 간편하게 할 수 있습니다.

var bVal = !!nVal;

물론, 문자열, Object, null, undefined 등에서도 동일한 방법으로 사용할 수 있습니다.

3. 변수에 값 입력하면서 사용하기

스크립트 계열의 언어에 대한 경험이 부족한 분들은 잘 사용하지 않는 방법인 것 같습니다. PHP 등에서도 가능하지만 함수형 언어의 특징을 지닌 JavaScript에서는 보다 재밌게 사용할 수 있습니다.

var obj = null;
if ( (obj = getObject())  obj.apply(1234) ) {
      
}

위 코드는 obj 가 존재하는지 안하는지에 대한 검사를 먼저 수행하고 obj가 있다면 obj.apply 메소드를 실행해서 결과값을 체크하는 조건을 수행하고 있습니다. 여러줄에 걸쳐쓰는 것보다 코드를 보다 깔끔하게 만들 수 있어 애용하는 방법입니다. ^^ 보다 다양한 조건식을 체크하는 것도 가능합니다.

4. 함수 자기자신을 대체하기

JavaScript 라는 언어는 몹시도 유연한 언어라서 함수나 메소드를 언제든 재정의 할 수 있습니다. 심지어 내장 메소드 마저도 가능하니 말 다했죠. ^^; 이런 특성을 이용해서 다음과 같이 응용해볼 수 있습니다.

  1  function g_getSelection() {
  2    if (window.getSelection) {
  3      window.g_getSelection = function(){ return window.getSelection(); };
  4    } else if (document.selection) {
  5      window.g_getSelection = function(){ return document.selection; };
  6    } else {
  7      window.g_getSelection = function() { alert("이 브라우저는 셀렉션을 지원하지 않습니다.") };
  8    }
  9  return g_getSelection();
 10  }

이렇게 작성해두면 최초에 실행될 때를 제외하면 해당 함수는 더 이상 비교구문을 거치지 않는 브라우저별 전용함수가 될 수 있습니다.

5. false 혹은 그에 준하는 값이 아닌 값만 받기

var someValue = v || a || r;

v, a, r 중에서 false 나 그에 준하는 값이 아닌 값을 전달 받습니다. 만약 v 가 문자열 “” 이고 a 가 숫자 8 이라면 someValue 의 값은 a의 값, 즉 숫자 8이 됩니다. 괄호를 묶는 코드와는 엄청난 차이가 있음에 주의하세요!

var someValue = (v || a || r); // 리턴값은 항상 true/false 

#끝~

분명 알고 계신 것도 있고 또 일부는 모르고 계신 분도 계셨을 겁니다. 작은 팁이지만 참고하셔서 도움이 되었으면 좋겠습니다. ^^

[JS] JavaScript 타이머 동작방식

Tip&Tech | 2008.02.26 10:43

jQuery의 개발자인 John Resig 이 자신의 블로그에 How JavaScript Timers Work 이라는 글을 올렸다. 여태까지 JavaScript Timer의 동작방식을 정확히 모르고 있었는데, 이를 알기 쉽게 설명해 준 매우 훌륭한 글이었다!

JavaScript의 타이머는 두 개의 메소드를 이용해서 설정할 수 있다. setTimeout 과 setInterval이 그것이다.

timers

자세한 설명은 위 링크를 참조하도록 하고, 핵심만 따로 추려서 얘기하자면…

  • JavaScript에는 쓰레드가 없기 때문에 모든 동작이 단일 쓰레드 내에서 작동한다.
  • 따라서, 타이머의 이벤트가 일어나더라도 바로 실행되는 것이 아니라 큐에 저장되며 다른 작업이 끝날 때까지 대기했다가 이벤트 콜백이 실행된다.
  • 또한 이로써 setTimeout을 연속적이고 재귀적으로 실행하는 것과 setInterval을 이용하는 것 사이에는 많은 차이가 있음을 알 수 있다.

위의 예는 아마도 모든 비동기 이벤트나 타이머에 적용될 듯 하다. 즉, 작업 중인 코드가 있었다면 비동기 이벤트가 완료된 시점에서 바로 실행되는 것이 아니라, 해당 코드가 종료되기를 기다리는 것이다.