JavaScript ES6에서 iterable과 iterator의 차이점은 무엇입니까?


14

iterable이 iterator와 동일합니까, 아니면 다른가요?

보인다 사양에서 가 반복 가능한 객체, 말,이다, objobj[Symbol.iterator], 호출 할 때 너무 함수를 참조하는 가진 개체를 반환 next반환 할 수 있습니다 방법 {value: ___, done: ___}개체를 :

function foo() {
    let i = 0;
    const wah = {
        next: function() {
            if (i <= 2) return { value: (1 + 2 * i++), done: false }
            else return { value: undefined, done: true }
        }
    };
    return wah;     // wah is iterator
}

let bar = {}        // bar is iterable

bar[Symbol.iterator] = foo;

console.log([...bar]);             // [1, 3, 5]   
for (a of bar) console.log(a);     // 1 3 5 (in three lines)

위의 코드 bar에서 반복 가능 wah하고 반복자이며 next()반복자 인터페이스입니다.

따라서 iterable과 iterator는 서로 다릅니다.

그러나 이제 일반적인 생성기 및 반복기 예제에서 :

function* gen1() {
    yield 1;
    yield 3;
    yield 5;
}

const iter1 = gen1();

console.log([...iter1]);                           // [1, 3, 5]
for (a of iter1) console.log(a);                   // nothing

const iter2 = gen1();
for (a of iter2) console.log(a);                   // 1 3 5 (in three lines)

console.log(iter1[Symbol.iterator]() === iter1);   // true

위의 경우 gen1생성기이며 iter1반복기이며 iter1.next()올바른 작업을 수행합니다. 그러나 iter1[Symbol.iterator]호출 될 때 iter1반복 하는 함수를 제공 합니다. 그래서 iter1모두는 반복 가능하고 반복자이 경우에?

또한, iter1실시 예 1에서 줄 수있는 반복 가능하기 때문에, 위의 예 1과 다른 [1, 3, 5]사용하여 원하는만큼 여러 번 [...bar]하면서, iter1반복 가능하지만,이 같은 반복자 때마다, 이는 자체를 반환하기 때문에 만 줄 것이다 [1, 3, 5]번.

그래서 우리는 iterable bar에 대해 몇 번이나 [...bar]결과를 줄 수 있는지 말할 수 있습니다 [1, 3, 5]. 그리고 iterable과 iterable이 동일합니까? 그리고 대답은, 그것들은 다른 것들이지만, iterable이 자체를 반복자로 사용할 때 그것들은 동일 할 수 있습니다. 그 맞습니까?



" 그래서 iter1이 경우 반복자 반복 가능하고 둘 다? "- 예. 모든 네이티브 반복자는 자신을 반환하여 반복 가능하므로 반복 가능을 기대하는 구문으로 쉽게 전달할 수 있습니다.
Bergi

답변:


10

예, 반복 가능 객체반복자는 여러 가지가 있지만 (예에서와 같이 자바 스크립트 자체에서 얻을 것을 모두 포함하여 대부분의 반복자 keys또는 values메소드 Array.prototype로부터 상속 발전기 기능이나 발전기) %의 IteratorPrototype %의 객체 이, Symbol.iterator같은 방법을 이:

[Symbol.iterator]() {
    return this;
}

결과적으로 모든 표준 반복자가 반복 가능합니다. 따라서 직접 사용하거나 for-of루프 등에서 사용할 수 있습니다 (반복자가 아닌 반복 가능).

keys배열 의 방법을 고려하십시오 : 배열의 키를 방문하는 배열 반복자를 반환합니다 (숫자로서의 인덱스). iterator를 반환 합니다 . 그러나 일반적인 용도는 다음과 같습니다.

for (const index of someArray.keys()) {
    // ...
}

for-of소요 반복 가능한 아닌 반복자를 , 왜 그 일을합니까?

반복자가 반복 가능하기 때문에 작동합니다. Symbol.iterator그냥 반환합니다 this.

다음은 제 책의 6 장에서 사용하는 예입니다. 모든 항목을 반복하고 첫 번째 항목은 건너 뛰고 slice하위 집합을 분리하는 데 사용하지 않으려 는 경우 반복자를 가져 와서 첫 번째 값을 읽을 수 있습니다. 그런 다음 for-of루프로 전달하십시오.

const a = ["one", "two", "three", "four"];
const it = a[Symbol.iterator]();
// Skip the first one
it.next();
// Loop through the rest
for (const value of it) {
    console.log(value);
}

이것은 모든 표준 반복자입니다. 때때로 사람들은 다음과 같이 수동으로 코딩 된 반복기의 예를 보여줍니다.

range거기에 의해 반환 된 반복자 는 iterable 이 아니므 로로 사용하려고하면 실패합니다 for-of.

반복 가능하게하려면 다음 중 하나를 수행해야합니다.

  1. Symbol.iterator위의 답변 시작 부분에 메소드를 추가하십시오. 또는
  2. 이미 해당 메소드가있는 % IteratorPrototype %에서 상속 받으십시오.

안타깝게도 TC39는 % IteratorPrototype % 개체를 얻는 직접적인 방법을 제공하지 않기로 결정했습니다. 간접적 인 방법이 있습니다 (배열에서 반복자를 가져 와서 프로토 타입을 가져 가면 % IteratorPrototype %로 정의 됨)하지만 고통입니다.

그러나 어쨌든 수동으로 반복자를 작성할 필요는 없습니다. 반환하는 생성기는 반복 가능하므로 생성기 함수 만 사용하십시오.


대조적으로, 모든 이터 러블이 반복자 인 것은 아닙니다. 배열은 반복 가능하지만 반복자는 불가능합니다. 문자열,지도 및 세트도 마찬가지입니다.


0

용어에 대한 좀 더 정확한 정의가 있으며, 이것이 더 명확한 답입니다.

ES6 사양MDN 에 따르면 :

우리가 할 때

function* foo() {   // note the "*"
    yield 1;
    yield 3;
    yield 5;
}

foo생성기 함수 라고 합니다 . 그리고 우리가 할 때

let bar = foo();

bar생성기 객체 입니다. 그리고 Generator 객체는 iterable 프로토콜과 iterator 프로토콜을 모두 준수합니다 .

더 간단한 버전은 반복자 인터페이스이며, 이는 단지 .next()방법 일뿐 입니다.

반복 가능한 프로토콜은 다음과 같습니다 개체에 대한 obj, obj[Symbol.iterator]"반복자 프로토콜에 부합, 제로 인수가 반환 함수 객체의"를 제공합니다.

MDN 링크제목에 따르면 생성기 개체를 "생성기"라고도 할 수 있습니다.

에 있습니다 ECMAScript를 6 이해 니콜라스 Zakas의 책 , 그는 아마 느슨하게 "발전기"로 "발전기 기능"이라고하고 "반복자"로 "생성기 객체". 테이크 아웃 포인트는 실제로 "제너레이터"와 관련이 있습니다. 하나는 생성기 함수이고 다른 하나는 생성기 객체 또는 생성기입니다. 생성기 객체는 반복 가능한 프로토콜과 반복자 프로토콜을 모두 준수합니다.

가에 부합하는 단지 객체 인 경우 반복자 프로토콜, 당신은 할 수 사용 [...iter]하거나 for (a of iter). 반복 가능한 프로토콜 을 따르는 객체 여야 합니다.

그런 다음 새로운 JavaScript 클래스 에도 새로운 초안이 아직 남아 있습니다. 그것은 다음과 같은 방법을 포함하여 더 큰 인터페이스를 가지고 forEach, map, reduce현재의 배열 인터페이스 등과 같은 새로운 사람의 take등을 drop. 현재 반복자는 next인터페이스 만있는 객체를 참조합니다 .

원래 질문에 대답하려면 반복자와 iterable의 차이점은 무엇입니까? 반복자는 인터페이스 .next()가있는 객체이고 iterable은 호출 될 때 인수가없는 함수를 제공 할 수 있는 객체 obj입니다 obj[Symbol.iterator]. 반복자를 반환합니다.

그리고 생성기는 반복 가능하고 반복자입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.