최근 온라인 강의를 듣던 중, JS의 for ... of 문의 동작에 대한 재미있는 내용을 배우게 되어 :)
본 포스팅을 통해 관련 내용을 복습 겸 정리해 보고자 합니다!
잘못된 내용에 대한 피드백은 언제나 감사드립니다! (_ _)
[인프런] 함수형 프로그래밍과 Javascript ES6+
MDN 문서 - for ... of
MDN 문서 - Iteration Protocols
왜 Object(객체)는 Iterable object가 아닌 것일까? (iterable과 iterator에 대해 알아보자!)
P.S 서두에서 언급한 강의는 참고 자료 제일 위에 적어 둔 <함수형 프로그래밍과 Javascript ES6+>입니다!
본 포스팅의 주요 내용 역시, 해당 강의 내용에 기반을 두고 있음을 밝힙니다 :)
const arr = [1, 2, 3, 4, 5];
for (const element of arr) {
console.log(element);
}
[ 출력 ]
1
2
3
4
5
[ 출처 : MDN Docs ]
The for...of statement executes a loop that
operates on a sequence of values sourced from an iterable object.
Iterable objects include instances of built-ins such as Array, String, TypedArray, Map, Set, NodeList...
for ... of 문은 Iterable Object에 포함된 일련의 값들에 대해 동작하는 루프를 실행!Array , String , Map , Set 등 built-in된 인스턴스들을 포함합니다! [ Iterable Object ]
Iterable Object란, Iteration Protocol 이라는 특정한 프로토콜(규약)을 따르는 객체를 말합니다!
그리고 이 Iteration Protocol은,
다시 Iterable Protocol과 Iterator Protocol로 나뉩니다!
[ 출처 : MDN Docs ]
The iterable protocol allows JavaScript objects to define or customize their iteration behavior...
In order to be iterable, an object must implement the [Symbol.iterator]() method, meaning that the object (or one of the objects up its prototype chain) must have a property with a [Symbol.iterator] key which is available via constant Symbol.iterator...
[Symbol.iterator]
A zero-argument function that returns an object, conforming to the iterator protocol.
Iterable Protocol은 자바스크립트 객체의 순회 동작, 그리고 순회 동작의 커스터마이징을 가능케 한다!
Iterable이 되기 위해, 객체는 [Symbol.iterator] 메서드를 구현해야 한다!
여기서 [Symbol.iterator] 메서드는,
Iterator Protocol을 따르는 객체를 반환해야 한다.
[ 출처 : MDN Docs ]
The iterator protocol defines a standard way to produce a sequence of values (either finite or infinite), and potentially a return value when all values have been generated.
An object is an iterator when it implements a next() method...
next() 메서드를 구현해야 함![ 출처 : MDN Docs ]
A function that accepts zero or one argument and returns an object conforming to the IteratorResult interface.
IteratorResult 인터페이스에 맞는 객체를 반환해야 합니다!done : Iterator의 순회가 종료되었는지 여부를 나타내는 booleanvalue : Iterator가 반환한 값으로, done이 true일 때는 생략할 수 있습니다.// built-in Iterable인 Set을 초기화합니다.
const setA = new Set([1,2,3]);
// Symbol.iterator 메서드를 호출하여, Iterator 객체를 얻습니다!
const iter = setA[Symbol.iterator]();
iter.next();
iter.next();
iter.next();
iter.next();
[ 출력 ]
{ value : 1, done : false }
{ value : 2, done : false }
{ value : 3, done : false }
{ value : undefined, done : true }
지금까지 for...of 문을 사용할 수 있는 Iterable 객체와, Iterable 객체가 따르는 Iteration Protocol에 대해 간단히 살펴 보았습니다!
→ for...of 문은 Iterable 객체에 대해 사용이 가능!
→ Iterable / Iterator 프로토콜을 따라, Iterable 객체의 개별 값들을 순회!
const arr = [1,2,3];
// [Symbol.iterator] 메서드를 임의로 삭제
arr[Symbol.iterator] = null;
for (const a of arr) {
console.log(a)
}
[ 출력 ]
TypeError : arr is not iterable
→ for...of 문은 Iterable / Iterator 프로토콜을 따라 동작하기 때문에, 해당 프로토콜의 [Symbol.iterator] 메서드를 임의로 지워주면 TypeError가 발생합니다! :)
자바스크립트의 전개 연산자(...)도 역시 Iterable / Iterator 프로토콜을 따릅니다!
const arr = [1,2];
// 역시 임의로 [Symbol.iterator] 메서드를 삭제
arr[Symbol.iterator] = null;
console.log([...arr]);
[ 출력 ]
TypeError : arr is not iterable
그래서, [Symbol.iterator] 메서드를 임의로 지워주면 역시 동일한 에러가 발생하네요! :)
자바스크립트의 for...of 문은 Iterable Object에 대해 사용할 수 있다!
Iterable Object란 Iteration Protocol을 따르고 있는 객체를 말하며,
Iteration Protocol의 종류는 Iterable Protocol과 Iterator Protocol로 구분된다 :)
[Symbol.iterator] 메서드를 구현!value 와, 순회 종료 여부를 나타내는 done 을 반환하는 메서드인 next() 를 구현!