Outsider's Dev Story

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

prototype.js의 Enumerable의 each() 사용하기

prototype.js에서는 Enumerations을 다루기 위한 Enumerable이라는 클래스를 제공하고 있고 Enumerable에 포함된 수많은 메서드가 있지만 그중에 each()는 단연 돋보인다. 기본적으로 Enumerable에서 each()가 대부분의 메서드의 로직의 기본이기도 하다. 나도 쓴지는 얼마 안됐는데 이거좀 최고다..ㅋ

다른 언어에 많이 있는 foreach같은 거랑 비슷한 메서드로 Iteration기능을 담당하고 있다. API를 보면 each()에 대한 정의가 다음과 같이 되어 있다.

each(iterator[, context]) -> Enumerable

솔직히 정의는 나중에 알고보면 아~ 그런가보다 하지 처음에 보면 이해하기가 어렵다. 사용법은 오나전 직관적이다. 배열이나 컬렉션등을 놓고 그냥 each로 루프를 돌려주면 된다.

var arr = ['11', '22', '33', '44', '55'];
arr.each(function(a) {
    alert(a);
});

위에처럼 사용한다. 배열에 each로 확장해 주고 안쪽에 function을 넣어서 필요한 기능을 수행한다. 반드시 function이 들어가야 되는 것은 아니지만 대개의 경우는 function을 수행할 꺼라고 생각한다. function을 사용할 때 첫번째 파라미터로는 순회돌면서 현재의 엘리먼트가 튀어나온다. 위의 예에서는 alert로 11부터 55까지 5번의 alert() 발생한다.

var arr = ['11', '22', '33', '44', '55'];
arr.each(function(a, idx) {
   alert(idx);
});

function에 2번째 파라미터를 사용하면 인덱스번호를 받을 수 있다. 여기서 인덱스는 대개의 배열처럼 0부터 시작한다. 위의 예에서는 0~4까지 5번의 alert()가 발생한다.

한눈에 보아도 for(i=0; i< length;i++)보다 훨씬 사용하기가 편하다. JSON배열도 마음것 순회할 수 있고 prototype.js에서는 컬렉션등이 Enumerable이랑 연계가 되기 때문에 배열처럼 생겼다 싶으면 그냥 다 each()를 사용해 주면 된다. HTML 엘리먼트의 객체들도 each를 이용해서 편리하게 사용할 수 있고 배열상수를 쉽게 만들수 있는 함수도 제공하고 있다. 내부에서는 다들 each()를 사용하기는 하지만 Enumerable이 제공하는 다른 메서드들과 같이 사용하면 복잡한 순회문 또는 이중,삼중으로 해주어야 하는 순회문을 상당히 직관적으로 간단히 작성할 수 있다.




순회를 할때는 필요한게 2가지 있는데 바로 순회 멈춤과 순회를 건너뛰는 기능이고 대부분의 언어에서는 break와 continue라는 명령어로 사용하고 있다. each()에서는 throw $break;와 return;을 사용해 주면 된다.
throw $break;를 사용하면 순회자체가 종료되고 return; 하면 다음 순회로 바로 건너뛴다. 1.5버전에서는 throw $continue;를 사용했었는데 이제는 사용하지 않고 그냥 return;을 사용하면 된다.





그리고 each()를 사용할 때 또 고려해야 될 문제중에 하나가 this에 대한 부분이다. 클래스를 만들어서 사용할 경우 멤버변수나 멤버함수의 경우에는 this지시자를 통해서 사용하는데 each()안에 들어가는 순간은 this가 해당 클래스가 아닌 each에서 순회도는 아이템을 가르키게 된다. 이럴땐 바인드를 사용하면 된다.

var arr = ['11', '22', '33', '44', '55'];
arr.each(function(a, idx) {
   alert(idx);
}.bind(this));

이렇게 bind()를 사용하면 each()내에서 this가 바인드한 Object를 가르키게 된다. bind()를 꼭 this에다가 사용해야 하는 것은 아니다.
2008/11/06 02:01 2008/11/06 02:01