이터러블과 이터레이터

5_wintaek·2025년 4월 1일
0

이터러블(iterable)

이터러블이란 반복 가능한 객체를 의미합니다.즉 요소를 하나씩 차례대로 접근할 수 있는 객체를 말합니다.

  • for...of 문으로 순회할 수 있습니다.
  • 전개 연산자(...)를 사용할 수 있습니다.
  • Symbol.iterator 메서드를 가지고 있어야 합니다. (이 메서드는 이터레이터(Iterator)를 반환합니다.)

배열

const arr = [1, 2, 3];
for (const item of arr) {
  console.log(item); // 1, 2, 3
}

문자열

const str = "hello";
for (const char of str) {
  console.log(char); // h, e, l, l, o
}

이터레이터(iterator)

{value : 값 , done : true/false} 형태의 이터레이터 객체를 리턴하는 next() 메서드를 가진 객체.next 메서드로 순활할 수 있는 객체입니다.

const arr = [1,2,3]; //arr는 그냥 평범한 배열

const iter = arr[Symbol.iterator](); 
/*
문법 파헤치기 : key값을 문자열이 아닌 변수로 주기위해 arr[변수] 형태를 가진다.
위 사진에서 보듯이, Symbol.iterator 라는 key값을 가지고 value는 함수이다. 
이를 접근해서 함수실행() 시키면 이터레이터 객체가 반환되어 iter에 담기게 된다.
*/

iter.next()
//>{value:1,done: false}
iter.next()
//>{value:2, done: false},
iter.next()
//{value:3, done: false}
iter.next()
//{value: undefined, done: true}

유사배열 vs 이터러블

이터러블(iterable) : 위에서 설명한 바와 같이 메서드 Symbol.iterator가 구현된 객체.
유사 배열(array-like) : 인덱스와 length 프로퍼티가 있어서 배열처럼 보이는 객체.

우선 배열과 유사배열의 차이점을 알아보겠습니다.

var array = [1, 2, 3];
array; // [1, 2, 3]
var nodes = document.querySelectorAll('div'); // NodeList [div, div, div, div, div, ...]
var els = document.body.children; // HTMLCollection [noscript, link, div, script, ...]

위 예제에서는 els 와 nodes 가 유사배열이고 array가 배열입니다. 겉만 봐서는 잘 모르지만 Array.isArray메서드를 사용해서 뭐가 배열인지 확인해보겠습니다.

Array.isArray(array); // true
Array.isArray(nodes); // false
Array.isArray(els); // false

직접 배열 리터럴로 선언한 array만 배열입니다. nodes나 els처럼 []로 감싸져 있지만 배열이 아닌 이들을 유사배열이라고 합니다.

let arrayLike = { // 인덱스와 length프로퍼티가 있음 => 유사 배열
  0: "Hello",
  1: "World",
  length: 2
};


for (let item of arrayLike) {} // Symbol.iterator가 없으므로 에러 발생

이터러블과 유사 배열은 배열이 아니기 떄문에 push,pop 등의 메서드를 지원하지 않습니다.

배열과 유사배열을 구분해야 하는 이유는, 유사배열의 경우 배열의 메서드를 쓸 수 없기 때문입니다.

어떻게 하면 이터러블과 유사 배열에 메서드를 적용할 수 있을까요 ?

Array.from 메서드

Array.from은 이터러블이나 유사 배열을 받아 '진짜'Array를 만들어 줍니다.

let arrayLike = { //유사배열
  0: "Hello",
  1: "World",
  length: 2
};
Array.from(arrayLike); // ["Hello", "World"]


let arr = Array.from(arrayLike); // ["Hello", "World"] 배열이 됨으로서 이터러블 객체도 된다.
for (let item of arr) {} // 1,2,3,4,5 (배열-문자열 형 변환이 제대로 동작합니다.)

Map과 Set 자료형도 이터러블

맵과 셋은 독리된 자료형이지 객체나 배열이 아닙니다.
그럼에도 불구하고 for..of문과 동작하는 이유는 인덱스로 접근하는게 아닌 이터러블 프로토콜을 따르고 있기 때문입니다.
자체적으로 내장 forEach()메서드를 지원하기도 합니다.

const set = new Set([1,2,3])
for (cosnt a of set) console.log(a) // 1,2,3
const map = new Map([['a',1],['b',2],['c',3]]);
// Map(3) {"a" => 1, "b" => 2, "c" => 3}

const iter = map[Symbol.itertator](); // 심볼.이터레이터가 자체 내장되었기에 불러오기만 하면
iter.next();
// {value: Array(2), done: false}


for(const a of map)
    console.log(a); // ['a',1],['b',2],['c',3]
profile
물음표를 느낌표로 바꾸는 개발자

0개의 댓글