티스토리 뷰

유사 배열 🤔

이번에는 유사 배열, 정확히는 유사 배열 객체(Array-like object)를 만들어 보려 합니다. 유사 배열 객체는 length 프로퍼티를 가지고 있으며, for-in을 통해 요소 순회가 가능한 객체를 의미합니다. 다만 결정적으로 배열의 메소드는 사용할 수 없기 때문에 유사하다는 의미에서 유사 배열이라 부르고 있습니다.

 

ES6 이전에는 저마다 규칙을 가지고 유사 배열을 구현했지만, ES6부터는 순회 가능한 구조에 이터레이션 프로토콜을 구현하면 유사 배열을 쉽게 만들 수 있습니다. 이터레이션 프로토콜을 구현하면 for-in, for-of와 같은 순회 문법이나 스프레드 문법, 디스트럭쳐링을 사용할 수 있습니다.

 

이터레이션 프로토콜 ⚡️

이터레이션 프로토콜(Iteration Protocol)이란, 순회 가능한 구조를 만들기 위해 정해진 규칙입니다. Symbol.iterator를 프로퍼티 키로 사용한 객체를 직접 구현하거나, 상속 받은 Symbol.iterator 메소드를 직접 호출함으로써 프로토콜을 준수한 이터레이터를 반환 받을 수 있습니다.

 

const array = [1, 2, 3];

// 이터레이터 반환
const iterator = array[Symbol.iterator]();

console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: undefined, done: true }

 

배열은 이터레이션 프로토콜을 준수한 데이터 컬렉션이기 때문에, Symbol.iterator 프로퍼티가 존재합니다. 이를 통해 호출되고 반환된 이터레이터는 next 메소드를 가지고 있으며, 호출을 통해 순회 결과를 나타내는 이터레이터 리절트 객체(Iterator Result Object)를 반환 받을 수 있습니다. 이 객체는 현재 포인터가 가리키는 요소와 순회가 완료되었는지 여부를 담고 있습니다.

 

for-of는 이터레이터를 순회하면서 내부적으로 next 메소드를 호출하며, done의 값이 true가 될 때 순회를 종료합니다.

 

마지막으로 이터레이션 프로토콜을 준수한 피보나치 함수를 만들면서 마무리 하겠습니다.

 

피보나치 수열이란 첫 째항과 둘 째항이 1이며, 셋 째항부터는 (n-1)+(n-2)인 수열입니다.

 

const fibonacci = function (max) {
  let [pre, cur] = [0, 1];

  return {
    [Symbol.iterator]() {
      return this;
    },
    next() {
      [pre, cur] = [cur, pre + cur];
      return { value: cur, done: cur >= max };
    },
  };
};

for (const num of fibonacci(10)) {
  // 1 2 3 5 8
  console.log(num);
}

 

이터레이션 프로토콜을 준수하면서 피보나치 수열을 간단하게 구현했습니다. 여기서 done을 빼면 무한 수열을 구현할 수도 있는데, 이 때 지연 평가(Lazy Evaluation)가 적용됩니다. 지연 평가는 데이터를 미리 메모리에 확보하지 않고, 필요한 순간에 생성하는 기법입니다.

 

참고 📖

What is array like object in JavaScript

이터레이션과 프로토콜

 

 

 

 

댓글