iterable 객체

양주영·2021년 8월 26일
0

javascript

목록 보기
9/42

iterable 객체


반복 가능한(iterable, 이터러블) 객체는 배열을 일반화한 객체이다. 이터러블 이라는 개념을 사용하면 어떤 객체에든 for..of 반복문을 적용할 수 있다.

반복 가능한 객체를 다른 객체와 구분짓는 특징은, 객체의 Symbol.iterator 속성에 특정 형태의 함수가 들어있다면, 이를 반복 가능한 객체 혹은 줄여서 iterable이라 부르고, 해당 객체는 iterable protocol을 만족한다고 말한다.

내장된 생성자 중 iterable 객체를 만들어내는 생성자에는 아래와 같은 것들이 있다.

  • String
  • Array
  • Typed array
  • Map
  • Set


- for..of구문

Iterator 객체에는 for..of 구문을 사용할 수 있다.

for (variable of iterable) {
	//구문
}

variable에는 const, let, var로 정의한 어떤 변수든 가능하고 iterable에는 iterable 객체만 가능하다.

let arr = ‘iterable’;
for ( let value of arr ){
	console.log(value);
} 


Symbol.iterator


이터러블로 만들기 위해서 객체에 Symbol.iterator라는 메서드를 추가해 아래와 같은 일이 벌어지도록 해야한다.
1. for..of가 시작되자마자 for..of는 Symbol.iterator를 호출한다(Symbol.iterator가 없으면 에러가 발생다). Symbol.iterator는 반드시 이터레이터(iterator, 메서드 next가 있는 객체) 를 반환해야 한다.
2. 이후 for..of는 반환된 객체(이터레이터)만을 대상으로 동작한다.
3. for..of에 다음 값이 필요하면, for..of는 이터레이터의 next()메서드를 호출한다.
4. next()의 반환 값은 {done: Boolean, value: any}와 같은 형태이어야 한다. done=true는 반복이 종료되었음을 의미. done=false일땐 value에 다음 값이 저장.

let range = {
  from: 1,
  to: 5
};

// 1. for..of 최초 호출 시, Symbol.iterator가 호출됩니다.
range[Symbol.iterator] = function() {

  // Symbol.iterator는 이터레이터 객체를 반환합니다.
  // 2. 이후 for..of는 반환된 이터레이터 객체만을 대상으로 동작하는데, 이때 다음 값도 정해집니다.
  return {
    current: this.from,
    last: this.to,

    // 3. for..of 반복문에 의해 반복마다 next()가 호출됩니다.
    next() {
      // 4. next()는 값을 객체 {done:.., value :...}형태로 반환해야 합니다.
      if (this.current <= this.last) {
        return { done: false, value: this.current++ };
      } else {
        return { done: true };
      }
    }
  };
};

// 이제 의도한 대로 동작합니다!
for (let num of range) {
  alert(num); // 1, then 2, 3, 4, 5
}


문자열은 이터러블이다.


배열과 문자열은 가장 광범위하게 쓰이는 내장 이터러블이다.

for..of는 문자열의 각 글자를 순회한다.

for (let char of "test") {
  // 글자 하나당 한 번 실행됩니다(4회 호출).
  alert( char ); // t, e, s, t가 차례대로 출력됨
}

서로게이트 쌍(surrogate pair)에도 잘 동작한다.

let str = '𝒳😂';
for (let char of str) {
    alert( char ); // 𝒳와 😂가 차례대로 출력됨
}


이터레이터를 명시적으로 호출하기


let str = "Hello";

// for..of를 사용한 것과 동일한 작업을 합니다.
// for (let char of str) alert(char);

let iterator = str[Symbol.iterator]();

while (true) {
  let result = iterator.next();
  if (result.done) break;
  alert(result.value); // 글자가 하나씩 출력됩니다.
}

이터레이터를 명시적으로 호출하는 경우는 거의 없는데, 이 방법을 사용하면 for…of를 사용하는 것보다 반복 과정을 더 잘 통제할 수 있다는 장점이 있다. 반복을 시작헀다가 잠시 멈춰 다른 작업을 하다가 다시 반복을 시작하는 것과 같이 반복 과정을 여러 개로 쪼개는 것이 가능하다.



이터러블과 유사 배열


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

이터러블 객체이면서 유사배열 객체인 문자열이 대표적인 그 예이다.
이터러블 객체라고 해서 유사 배열 객체는 아니고, 유사 배열 객체라고 해서 이터러블 객체인 것도 아니다.

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

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


Array.from


Array.from는 이터러블이나 유사 배열을 받아 ‘진짜’ Array를 만들어준다.
유사 배열 객체나 반복 가능한 객체를 얕게 복사해 새로운 Array 객체를 만든다.
이 과정을 거치면 이터러블이나 유사 배열에 배열 메서드를 사용할 수 있다.

let arrayLike = {
  0: "Hello",
  1: "World",
  length: 2
};

let arr = Array.from(arrayLike); // (*)
alert(arr.pop()); // World (메서드가 제대로 동작합니다.)

Array.from은 객체를 받아 이터러블이나 유사 배열인지를 조사하고,
넘겨 받은 인수가 이터러블이나 유사 배열인 경우
새로운 배열을 만들고 객체의 모든 요소를 새롭게 만든 배열로 복사한다.





참조 : https://ko.javascript.info/iterable

profile
뚜벅뚜벅

0개의 댓글