[JavaScript] for-of와 Iterator
Front-End/JavaScript

[JavaScript] for-of와 Iterator

 

 

 

for-of문

 

for(let value of myArray){
  console.log(value);
}

 

for-in 문이 객체의 속성들을 순회하기 위한 구문이라면, for-of 문은 배열의 요소들, 즉 data 를 순회하기 위한 구문이다. 정확히는 일반 Object 요소를 제외한 Array, Map, Set 등의 객체 타입을 순회할 수 있다. (추가로 String도 가능하다. 문자열로 이루어진 배열로 보기 때문)

 

forEach와는 다르게 break, continue, 그리고 return 구문과 함께 사용할 수 있다.

 

for-of문은 어떤 메소드를 반복 호출하는 방식으로 동작한다. Array, Map, Set 등의 객체들은 공통적으로 이터레이터(iterator) 메소드를 제공한다. 일반 객체는 이터레이터 메소드를 제공하지 않기 때문에 for-of문으로 순회가 불가능하다.

 

 

Array의 속성을 살펴보면 Symbol.iterator가 포함되어있다.

 

 

반면 일반 Object에는 존재하지 않는다.

 

Array와 같이 이터레이터 메소드를 제공하여 for-of문으로 순회 가능한 객체를 '이터러블(Iterable)' 이라 한다.

 

 

 

 

 

Iterable의 정의

 

이터러블의 정의는 다음과 같다.

 

Symbol.iterator 메소드를 구현하거나 프로토타입 체인에 의해 상속한 객체로, for-of 문에서 순회할 수 있으며 Spread 문법의 대상으로 사용할 수 있다.

 

일반 객체도 간단하게 이터러블로 만들 수 있다.
객체 안에 [Symbol.iterator]()를 구현하면 된다. 이렇게 구현된 이터러블을 커스텀 이터러블이라 한다.

당신이 어떤 객체에든 myObject.toString() 메소드를 추가하면 JS가 이를 통해 해당 객체를 문자열로 변환하는 방법을 알아내는 것과 마찬가지로, 어떤 객체에든 [Symbol.iterator]메소드를 추가하면 JS는 해당 객체를 어떻게 순회(loop)해야 하는지 알아낸다.

 

 

 

 

💡 .iterator()가 아닌 [Symbol.iterator] 메소드를 사용하는 이유는 무엇인가

기존에 작선된 코드에서 어떤 객체가 이미 .iterator()라는 메소드를 갖고 있다면 문제가 생긴다. 그래서 iterator라는 평범한 문자열 이름 대신 Symbol을 사용한 고유한(어떤 코드와도 충돌하지 않는) 메소드를 정의해준 것이다.

🔗Symbol에 대해 알고싶다면 참고

 

 

 

 

Symbol.iterator()

[Symbol.iterator]() 는 새로운 이터레이터 객체를 반환한다.

 

 

이터레이터 객체란 next() 메소드를 가진 객체를 말한다.

next() 메소드는 이터러블의 각 요소를 순회하기 위한 포인터의 역할을 하며, 호출시마다 valuedone 속성을 가진 이터레이터 result 객체를 반환한다.

  • value는 현재 순회중인 이터러블의 값을 반환하고,
  • done은 이터러블의 순회 완료 여부를 반환한다.

 

for-of 문은 [Symbol.iterator]()메소드의 호출로 시작하여 next()를 반복적으로 호출하며 객체를 순회한다. 순회하면서 next()가 반환한 이터레이터 result 객체의 value 프로퍼티 값을 for-of문의 변수에 할당한다.

 

// 배열은 이터러블이다.
const array = [1, 2, 3];

// 이터러블은 Symbol.iterator 메소드를 소유한다.
// Symbol.iterator 메소드는 이터레이터를 반환한다.
let iter = array[Symbol.iterator]();

// 이터레이터는 next 메소드를 소유한다.
// next 메소드는 이터레이터 result 객체를 반환한다.
console.log(iter.next()); // {value: 1, done: false}
console.log(iter.next()); // {value: 2, done: false}
console.log(iter.next()); // {value: 3, done: false}
console.log(iter.next()); // {value: undefined, done: true}

위의 코드에서 보면, next()를 호출할 때 마다 요소를 하나씩 순회하며, 순회가 끝났을 때는 done: true를 반환한다.

 

 

 

 

 

 

 

 

📌
http://hacks.mozilla.or.kr/2015/08/es6-in-depth-iterators-and-the-for-of-loop/