본문 바로가기

자바스크립트-스터디[2021-10-05~완료]

34장 이터러블

널두 : 33장. 7번째타입 symbol (p.7) + MDN
데브워니 : 34장. 이터러블 (p.11)
kei : 35장. 스프레드 문법 (p.6) + MDN
노아 : 36장. 디스트럭처링 할당 + 37장. Set과 Map (p.22)

 

for... of 는 새로 나왔어요

 

 

 

for...in

 

출력하고 싶으면

쌩코딩: obj.name; obj.age;

 

 

 

부모꺼를 출력한다.
부모꺼 가져오는거 방지

 

 

 

 

 

 

 

신 문법: for of 반복문

 

Array외에 String도 가능

 

 

 

특징: iterable한 자료형에만 사용 가능하다

 

 

 

 

html에 있는 여러 요소를 찾을 수 있다.

 


 

 

34.1 이터레이션 프로토콜

es6에서 도입됨

순회 가능한 데이터 컬렉션을 만들기 위해 에크마 스크립트 사양에 정의하여 미리 약속한 규칙이다.

이전의 순회 가능한 데이터 컬렉션

배열, 문자열, 유사 배열 객체, Dom 컬렉션 등은 통일된 규약 없이 각자 나름의 구조를 가지고

for문 forEach 메서드로 순회 했다.

 

 

이터러블 프로토콜 이터레이터 프로토콜
Symbol.iterator 프로퍼티 키로 사용한 메서드를 직접 구현,
상속 받은 Symbol.iterator 메서드를 호출하면 
이터레이터 프로토콜을 준수한
이터레이터(포인터)를 반환한다



이터레이터를 반환한다.
Symbol.iterator 메서드를 호출하면

이터레이터는 next 메서드를 가진다.
next를 호출하면 이터러블(객체)를 순회하여 
value, done 프로퍼티를 갖는 이터레이터 result 객체를 반환

이터레이터는 포인터 역할한다.

 

1) 이터러블 (iterable)

이터러블 : 이터러블 프로토콜을 준수한 객체

Symbol.iterator 프로퍼티 키로 사용한 메서드

 

1) 직접 구현한 객체

2) 프로토타입 체인을 통해 상속받은 객체

 

이터러블(객체)는 

for.. of 문으로 

 

배열, 문자열, Map, Set은 모두 이터러블이다.

 

const array = [1, 2, 3];

// Symbol.iterator 메서드를 상속받는다.
console.log(Symbol.iterator in array); // true

// for..of 문 사용
for(const item of array) {
  console.log(item);
}

// 스프레드 문법 사용
console.log([...array]); // [1, 2, 3]

// 디스트럭처링 할당
const [a, ...rest] = array;
console.log(a, rest); // 1, [2, 3]

 

결과

 

 

 

2) 이터레이터(iterator) == 포인터

이터러블의 Symbol.iterator 메서드를 호출하면 이터레이터를 반환한다. 이터레이터는 next 메서드를 갖는다.

이터레이터의 next 메서드는 이터러블의 각 요소를 순회하기 위한 포인터의 역할을 한다. 이터레이터의 next 메서드가 반환하는 객체의 value 프로퍼티는 현재 순회 중인 이터러블의을 나타내고, done 프로퍼티는 이터러블의 순회 완료 여부를 나타낸다.

 

const array = [1, 2, 3];

// Symbol.iterator 메서드는 이터레이터를 반환
const iterator = array[Symbol.iterator]();

// next 메서드를 갖는다.
console.log('next' in iterator); // true

console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: undefined, done: true }

 

 

 

34.2 빌트인 이터러블

 

 

 

 

 

34.3 for... of 문

 

1) for.. of

특징: iterable한 자료형에만 사용 가능하다

 

내부적 기능

iterator의 next 메서드를 호출 -> 이터러블을 순회

내부 동작

2) for.. in

프로퍼티 어트리뷰트 [[Enumerable]] 값이 true인 프로퍼티를 순회하면서 열거한다.

프로퍼티 키 = symbol이면 안 읽어 온다.

반복문에서 출력 안됨
: enumerable 속성이 false라 반복문에서 출력되지 않는다.

person.nick 은 반복문에서 출력안됨

 

 

 

 

 

34.4 이터러블, 유사 배열 객체

유사 배열 객체

유사 배열 객체는 마치 배열처럼

인덱스로 프로퍼티 값에 접근할 수 있고

length 프로퍼티를 갖는 객체를 말한다.

 

유사 배열 객체는 length 프로퍼티를 갖기 때문에 for 문으로 순회할 수 있고,

인덱스를 나타내는 숫자 형식의 문자열을 프로퍼티 키로 가지기 때문에 인덱스로 프로퍼티 값에 접근할 수 있다.

 

const arrayLike = {
  0: 1,
  1: 2,
  2: 3,
  length: 3
};

for (let i = 0; i < arrayLike.length; i++) {
  console.log(arrayLike[i]); // 1 2 3
}

하지만 유사 배열 객체는 이터러블이 아닌 일반 객체다. 따라서 Symbol.iterator 메서드가 없기 때문에 for...of 문으로 순회할 수 없다.

 

for (const item of arrayLike) {
  console.log(item); // 1 2 3
}

// TypeError: arrayLike is not iterable

for.. of 안됨 for.. in 됨

 

 

유사 배열 객체 ---->> 이터러블 하기 까지?!

arguments
nodeList
HtmlCollection
배열

 

 

 

 

34.5 이터레이션 프로토콜의 필요성

for... of
스프레드 문법
배열 디스트럭처링 할당

 

 

 

 

 

34.6 사용자 정의 이터러블

일반 객체 -> 이터러블

일반 객체도 이터러블로 만들 수 있다.

사용자 정의 이터러블은 Symbol.iterator 메서드를 구현하고 Symbol.iterator 메서드가 next 메서드를 갖는 이터레이터를 반환하도록 한다. 또한 이터레이터의 next 메서드는 value와 done 프로퍼티를 가지는 객체를 반환한다.

 

1) 사용자 정의 이터러블 구현

const fibonacci = {
  [Symbol.iterator]() {
    let [pre, cur] = [0, 1];
    const max = 10; // 수열의 최대값
    
    return {
      next() {
        [pre, cur] = [cur, pre + cur];
        return { value: cur, done: cur >= max };
      }
    };
  }
};

for (const num of fibonacci) {
  console.log(num); // 1 2 3 5 8
}

 

 

2) 이터러블을 생성하는 함수 구현

수열의 최대 값을 외부에서 전달할 수 있도록 수정해 보자. 수열의 최대값을 인수로 전달받아 이터러블을 반환하는 함수를 만들면 된다.

 

const fibonacciFunc = function (max) {
  let [pre, cur] = [0, 1];
  
  // 이터러블 반환
  return {
    [Symbol.iterator]() {
      return {
        next() {
          [pre, cur] = [cur, pre + cur];
          return { value: cur, done: cur >= max };
      	}
      };
    }
  };
};

for (const num of fibonacciFunc(10)) {
  console.log(num); // 1 2 3 5 8
}

 

 

 

 

3) 이터러블이면서 이터레이터인 객체를 생성하는 함수 구현

fibonacciFunc 함수는 이터러블을 반환하기 때문에, 이터레이터를 생성하려면 이터러블의 Symbol.iterator 메서드를 호출해야 한다.

const iterable = fibonacciFunc(5);

const iterator = iterable[Symbol.iterator]();

console.log(iterator.next());

 

 

Symbol.iterator 메서드를 호출하지 않아도 되도록 코드를 수정해보자. fibonacciFunc 함수를 이터러블이면서 이터레이터인 객체를 생성하여 반환하는 함수로 변경하면 된다.

 

const fibonacciFunc = function (max) {
  let [pre, cur] = [0, 1];

  return {
    [Symbol.iterator]() { return this; },
    
    next() {
      [pre, cur] = [cur, pre + cur];
      return { value: cur, done: cur >= max };
    }
  };
};

let iter = fibonacciFunc(10);

// iter는 이터러블
for (const num of iter) {
  console.log(num); // 1 2 3 5 8
}

iter = fibonacciFunc(10);

// iter는 이터레이터
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: 5, done: false }
console.log(iter.next()); // { value: 8, done: false }
console.log(iter.next()); // { value: 13, done: true }

 

 

'자바스크립트-스터디[2021-10-05~완료]' 카테고리의 다른 글

39장 DOM  (0) 2022.02.04
33장 Symbol  (0) 2022.01.21
31장 정규표현식  (0) 2022.01.14
18장 함수와 일급 객체  (0) 2022.01.12
[27.8] 배열 메서드  (0) 2022.01.10