이터러블 프로토콜(Iterable Protocol)은 자바스크립트에서 객체가 이터러블(반복 가능한)하도록 만드는 규칙이나 약속을 말합니다. 이 프로토콜을 따르면, 해당 객체는 반복할 수 있는 데이터로 취급되며 for...of 문이나 스프레드 연산자 같은 이터레이션이 필요한 문법에서 사용할 수 있습니다.
Symbol.iterator
메서드: 이 메서드를 가진 객체는 이터러블로 간주됩니다.
이터레이터(Iterator)
: Symbol.iterator 메서드가 반환하는 객체는 이터레이터라고 하며, 이 이터레이터는 next()
메서드를 통해 값을 순차적으로 반환합니다.
자바스크립트의 기본 객체 중 많은 것들이 이터러블 프로토콜을 따릅니다. 예를 들어, 배열(Array)
, 문자열(String)
, Set
, Map
등이 이터러블입니다. 이 객체들은 내부적으로 Symbol.iterator 메서드를 가지고 있습니다.
console.log(
[][Symbol.iterator],
''[Symbol.iterator],
new Set()[Symbol.iterator],
new Map()[Symbol.iterator]
);
// 다른 타입의 인스턴스에는 없음
console.log(
(1)[Symbol.iterator],
(true)[Symbol.iterator],
{ x: 1 }[Symbol.iterator]
);
const arr = [1, 2, 3];
const arrIterator = arr[Symbol.iterator]();
console.log(arrIterator.next()); // { value: 1, done: false }
console.log(arrIterator.next()); // { value: 2, done: false }
console.log(arrIterator.next()); // { value: 3, done: false }
console.log(arrIterator.next()); // { value: undefined, done: true }
Set은 중복되지 않는 값들의 집합입니다. 배열처럼 여러개의 다양한 타입의 데이터를 담을 수 있습니다. 배열과의 차이점으로 동일한 값을 여러 번 포함할 수 없으며 값들의 순서가 무의미합니다.
const set = new Set();
// add: 요소 추가
set.add(1);
set.add('A');
set.add(true);
// has: 요소 포함 여부
set.has(2); // false
// delete: 요소 삭제
set.delete('A'); // 삭제 성공 여부인 true를 반환
// size 프로퍼티: 요소의 개수
console.log(set.size);
// clear 메서드: 모든 요소 삭제
set.clear();
배열을 인자로 넣으면 Set의 생성과 동시에 값의 초기화도 같이 됩니다. 배열의 중복된 값들을 제거할 수 있습니다.
const set = new Set([1, 1, 1, 'A', 'A', true]);
console.log(set); // {1, 'A', true}
Map은 key와 value의 쌍으로 이루어진 컬렉션입니다. 객체와의 차이점으로는 Map은 이터러블의 일종이기 때문에 이터러블의 기능들을 사용할 수 있으며 객체나 배열 등의 참조값을 key로 사용 가능 합니다. 키와 값을 자주 변경하는 경우 사용하기 적합하도록 설계되었습니다.
key의 중복이 불가하여, 해당 키가 있을 시 value값이 덮어씌워집니다.
const map = new Map();
// set 메서드: 키와 값의 쌍 추가
map.set('x', 1);
map.set(123, 'ABC');
map.set(true, { a: 1, b: 2 });
// [[키 쌍]...] 배열로 생성과 초기화를 같이할 수 있음
const map = new Map([
['x', 1],
[123, 'ABC'],
[true, { a: 1, b: 2 }],
]);
// has 메서드: key 포함 여부
map.has('x'); // true
// get 메서드: key로 value에 접근
map.get(123); // 'ABC'
// 참조값도 키로 사용 가능
const objKey = { x: 1, y: 2 };
const arrKey = [1, 2, 3];
map.set(objKey, 'OBJ_KEY');
map.set(arrKey, 'ARR_KEY');
// delete 메서드: 요소 제거 & 성공 여부 반환
map.delete('x'); // true
// size 프로퍼티: 요소의 개수
console.log(map.size);
// clear 메서드: 모든 요소 삭제
map.clear();
제너레이터(Generator)는 자바스크립트에서 반복 가능한 함수의 일종으로, 함수 실행을 중간에 멈췄다가 다시 재개할 수 있는 특별한 기능을 제공합니다. 제너레이터는 일반 함수와 달리 함수 실행을 중간에서 일시 정지(pause)하고, 필요할 때 재개(resume)할 수 있다는 점에서 독특합니다.
function*
: 제너레이터 함수는 function 키워드 뒤에 *(애스터리스크)를 붙여 선언합니다.
yield
: 제너레이터 함수 내부에서는 yield 키워드를 사용하여 함수 실행을 일시 정지하고, 값을 반환할 수 있습니다.
이터러블 프로토콜
: 제너레이터 함수는 이터러블 프로토콜을 따르므로 for...of 문에서 사용할 수 있습니다.
next()
메서드: 제너레이터는 이터레이터 객체를 반환하며, 이 객체의 next() 메서드를 호출할 때마다 yield 키워드가 있는 위치에서 멈췄던 곳부터 다시 실행을 시작합니다.
function* myGenerator() {
yield 1;
yield 2;
yield 3;
}
const gen = myGenerator(); // 제너레이터 객체를 반환
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }
console.log(gen.next()); // { value: undefined, done: true }