This page was translated from English by the community. Learn more and join the MDN Web Docs community.

View in English Always switch to English

๋ฐ˜๋ณต๊ธฐ ๋ฐ ์ƒ์„ฑ๊ธฐ

์ปฌ๋ ‰์…˜ ๋‚ด ๊ฐ ํ•ญ๋ชฉ ์ฒ˜๋ฆฌ๋Š” ๋งค์šฐ ํ”ํ•œ ์—ฐ์‚ฐ์ž…๋‹ˆ๋‹ค. JavaScript๋Š” ๊ฐ„๋‹จํ•œ for ๋ฃจํ”„์—์„œ map() ๋ฐ filter()์— ์ด๋ฅด๊ธฐ๊นŒ์ง€, ์ปฌ๋ ‰์…˜์„ ๋ฐ˜๋ณตํ•˜๋Š” ๋งŽ์€ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ณต๊ธฐ(iterator) ๋ฐ ์ƒ์„ฑ๊ธฐ(generator)๋Š” ๋ฐ˜๋ณต ๊ฐœ๋…์„ ํ•ต์‹ฌ ์–ธ์–ด ๋‚ด๋กœ ๋ฐ”๋กœ ๊ฐ€์ ธ์™€ for...of ๋ฃจํ”„์˜ ๋™์ž‘(behavior)์„ ์‚ฌ์šฉ์ž ์ •์˜ํ•˜๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์ž์„ธํ•œ ๋‚ด์šฉ์€, ๋‹ค์Œ์„ ์ฐธ์กฐํ•˜์„ธ์š”:

๋ฐ˜๋ณต์ž

JavaScript์—์„œ ๋ฐ˜๋ณต์ž(Iterator)๋Š” ์‹œํ€€์Šค๋ฅผ ์ •์˜ํ•˜๊ณ  ์ข…๋ฃŒ์‹œ์˜ ๋ฐ˜ํ™˜๊ฐ’์„ ์ž ์žฌ์ ์œผ๋กœ ์ •์˜ํ•˜๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. ๋” ๊ตฌ์ฒด์ ์œผ๋กœ ๋งํ•˜์ž๋ฉด, ๋ฐ˜๋ณต์ž๋Š” ๋‘ ๊ฐœ์˜ ์†์„ฑ( value, done)์„ ๋ฐ˜ํ™˜ํ•˜๋Š” next() ๋ฉ”์†Œ๋“œ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด์˜ Iterator protocol์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ์‹œํ€€์Šค์˜ ๋งˆ์ง€๋ง‰ ๊ฐ’์ด ์ด๋ฏธ ์‚ฐ์ถœ๋˜์—ˆ๋‹ค๋ฉด done ๊ฐ’์€ true ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ value๊ฐ’์ด done ๊ณผ ํ•จ๊ป˜ ์กด์žฌํ•œ๋‹ค๋ฉด, ๊ทธ๊ฒƒ์€ ๋ฐ˜๋ณต์ž์˜ ๋ฐ˜ํ™˜๊ฐ’์ด ๋ฉ๋‹ˆ๋‹ค.

๋ฐ˜๋ณต์ž๋ฅผ ์ƒ์„ฑํ•˜๋ฉด next() ๋ฉ”์†Œ๋“œ๋ฅผ ๋ฐ˜๋ณต์ ์œผ๋กœ ํ˜ธ์ถœํ•˜์—ฌ ๋ช…์‹œ์ ์œผ๋กœ ๋ฐ˜๋ณต์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ณต์ž๋ฅผ ๋ฐ˜๋ณต์‹œํ‚ค๋Š” ๊ฒƒ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ํ•œ ๋ฒˆ์”ฉ๋งŒ ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ๋ฐ˜๋ณต์ž๋ฅผ ์†Œ๋ชจ์‹œํ‚ค๋Š” ๊ฒƒ์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰ ๊ฐ’์„ ์‚ฐ์ถœํ•˜๊ณ ๋‚˜์„œ next()๋ฅผ ์ถ”๊ฐ€์ ์œผ๋กœ ํ˜ธ์ถœํ•˜๋ฉด {done: true}. ๊ฐ€ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

JavaScript์—์„œ ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ๋ฐ˜๋ณต์ž๋Š” ๋ฐฐ์—ด ๋ฐ˜๋ณต์ž๋กœ, ๋ฐฐ์—ด์˜ ๊ฐ ๊ฐ’์„ ์ˆœ์„œ๋Œ€๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ๋ฐ˜๋ณต์ž๊ฐ€ ๋ฐฐ์—ด๋กœ ํ‘œํ˜„๋ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ์ƒํ•  ์ˆ˜ ์žˆ์ง€๋งŒ , ์ด๊ฒƒ์€ ์‚ฌ์‹ค์€ ์•„๋‹™๋‹ˆ๋‹ค. ๋ฐฐ์—ด์€ ์™„์ „ํžˆ ํ• ๋‹น๋˜์–ด์•ผ ํ•˜์ง€๋งŒ, ๋ฐ˜๋ณต์ž๋Š” ํ•„์š”ํ•œ๋งŒํผ๋งŒ ์†Œ๋ชจ๋˜๋ฏ€๋กœ ๋ฌด์ œํ•œ ์‹œํ€€์Šค๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ…Œ๋ฉด 0๋ถ€ํ„ฐ ๋ฌดํ•œ๋Œ€์‚ฌ์ด์˜ ์ •์ˆ˜๋ฒ”์œ„์ฒ˜๋Ÿผ ๋ง์ด์ฃ .

์—ฌ๊ธฐ์— ์‹ค์Šตํ•  ์ˆ˜ ์žˆ๋Š” ์˜ˆ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. start์—์„œ end๊นŒ์ง€ step ์ˆ˜ ๋งŒํผ ๋„์–ด์ง„ ์ •์ˆ˜ ์‹œํ€€์Šค๋ฅผ ์ •์˜ํ•˜๋Š” ๊ฐ„๋‹จํ•œ ๋ฒ”์œ„ ๋ฐ˜๋ณต์ž๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ตœ์ข…์ ์œผ๋กœ ์‹œํ€€์Šค์˜ ํฌ๊ธฐ๊ฐ€ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

javascript
function makeRangeIterator(start = 0, end = Infinity, step = 1) {
  var nextIndex = start;
  var n = 0;

  var rangeIterator = {
    next: function () {
      var result;
      if (nextIndex < end) {
        result = { value: nextIndex, done: false };
      } else if (nextIndex == end) {
        result = { value: n, done: true };
      } else {
        result = { done: true };
      }
      nextIndex += step;
      n++;
      return result;
    },
  };
  return rangeIterator;
}

์œ„์˜ ๋ฐ˜๋ณต์ž๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค:

javascript
var it = makeRangeIterator(1, 4);

var result = it.next();
while (!result.done) {
  console.log(result.value); // 1 2 3
  result = it.next();
}

console.log("Iterated over sequence of size: ", result.value);

It is not possible to know reflectively whether a particular object is an iterator. If you need to do this, use Iterables.

Generator functions

์ž˜ ๋งŒ๋“ค์–ด์ง„ ๋ฐ˜๋ณต์ž(Iterator)๋Š” ์œ ์šฉํ•œ ๋„๊ตฌ์ธ ๋ฐ˜๋ฉด, ์ด๊ฒƒ์„ ์ƒ์„ฑํ•  ๋•Œ๋Š” ์ฃผ์˜ํ•ด์„œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ•ด์•ผ ํ•˜๋Š”๋ฐ, ๋ฐ˜๋ณต์ž ๋‚ด๋ถ€์— ๋ช…์‹œ์ ์œผ๋กœ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•  ํ•„์š”๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ƒ์„ฑ์ž(Generator) ํ•จ์ˆ˜๋Š” ์ด์— ๋Œ€ํ•œ ๊ฐ•๋ ฅํ•œ ๋Œ€์•ˆ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค: ์‹คํ–‰์ด ์—ฐ์†์ ์ด์ง€ ์•Š์€ ํ•˜๋‚˜์˜ ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•จ์œผ๋กœ์„œ ๊ฐœ๋ฐœ์ž๊ฐ€ iterative algorithm์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋Š” function* ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์„ฑ๋ฉ๋‹ˆ๋‹ค. ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ตœ์ดˆ๋กœ ํ˜ธ์ถœ๋  ๋•Œ, ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ ์–ด๋– ํ•œ ์ฝ”๋“œ๋„ ์‹คํ–‰๋˜์ง€ ์•Š๊ณ , ๋Œ€์‹  ์ƒ์„ฑ์ž๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š” ๋ฐ˜๋ณต์ž ํƒ€์ž…์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ƒ์„ฑ์ž์˜ next ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•จ์œผ๋กœ์„œ ์–ด๋–ค ๊ฐ’์ด ์†Œ๋น„๋˜๋ฉด, ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋Š” yield ํ‚ค์›Œ๋“œ๋ฅผ ๋งŒ๋‚  ๋•Œ๊นŒ์ง€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

์ƒ์„ฑ์ž ํ•จ์ˆ˜๋Š” ์›ํ•˜๋Š” ๋งŒํผ ํ˜ธ์ถœ๋  ์ˆ˜ ์žˆ๊ณ , ๋งค๋ฒˆ ์ƒˆ๋กœ์šด ์ƒ์„ฑ์ž๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค๋‹ค. ํ•˜์ง€๋งŒ, ๊ฐ ์ƒ์„ฑ์ž๋Š” ๋‹จ ํ•œ ๋ฒˆ๋งŒ ์ˆœํšŒ๋  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์œ„์˜ ์˜ˆ์ œ ์ฝ”๋“œ์— ์ƒ์„ฑ์ž๋ฅผ ์ ์šฉํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‘ ์ฝ”๋“œ์˜ ํ–‰์œ„๋Š” ๋™์ผํ•˜์ง€๋งŒ, ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•œ ์ชฝ์ด ์“ฐ๊ฑฐ๋‚˜ ์ฝ๊ธฐ๊ฐ€ ํ›จ์”ฌ ์‰ฝ์Šต๋‹ˆ๋‹ค.

javascript
function* makeRangeIterator(start = 0, end = Infinity, step = 1) {
  let n = 0;
  for (let i = start; i < end; i += step) {
    n++;
    yield i;
  }
  return n;
}

Iterables

๊ฐ์ฒด๋Š” ๊ฐ’์ด for..of ๊ตฌ์กฐ ๋‚ด์—์„œ ๋ฐ˜๋ณต๋˜๋Š” ๊ฒƒ ๊ฐ™์€ ๊ทธ ๋ฐ˜๋ณต ๋™์ž‘์„ ์ •์˜ํ•˜๋Š” ๊ฒฝ์šฐ ๋ฐ˜๋ณต์ด ๊ฐ€๋Šฅ(iterable)ํ•ฉ๋‹ˆ๋‹ค. Array ๋˜๋Š” Map๊ณผ ๊ฐ™์€ ์ผ๋ถ€ ๋‚ด์žฅ ํ˜•์€ ๊ธฐ๋ณธ ๋ฐ˜๋ณต ๋™์ž‘์ด ์žˆ์ง€๋งŒ ๋‹ค๋ฅธ ํ˜•(๊ฐ€๋ น Object)์€ ์—†์Šต๋‹ˆ๋‹ค.

๋ฐ˜๋ณต๊ฐ€๋Šฅํ•˜๊ธฐ ์œ„ํ•ด์„œ, ๊ฐ์ฒด๋Š” @@iterator ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ๊ฐ์ฒด( ํ˜น์€ ๊ทธ ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ์— ๋“ฑ์žฅํ•˜๋Š” ๊ฐ์ฒด ์ค‘ ํ•˜๋‚˜)๊ฐ€ Symbol.iterator ํ‚ค๋ฅผ ๊ฐ–๋Š” ์†์„ฑ์ด ์žˆ์–ด์•ผ ํ•จ์„ ๋œปํ•ฉ๋‹ˆ๋‹ค.

ํ•˜๋‚˜์˜ iterable์€ ๋‹จ ํ•œ ๋ฒˆ, ํ˜น์€ ์—ฌ๋Ÿฌ๋ฒˆ ๋ฐ˜๋ณต๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์–ด๋–ค ์ˆœ๊ฐ„์— ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•  ์ง€๋Š” ํ”„๋กœ๊ทธ๋ž˜๋จธ์—๊ฒŒ ๋‹ฌ๋ ค์žˆ์Šต๋‹ˆ๋‹ค. ๋‹จ ํ•œ ๋ฒˆ ๋ฐ˜๋ณต๊ฐ€๋Šฅํ•œ iterable(e.g. Generator)์€ ๊ด€์Šต์ ์œผ๋กœ ์ž์‹ ์˜ @@iterator ๋ฉ”์†Œ๋“œ๋กœ๋ถ€ํ„ฐ this๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด, ์—ฌ๋Ÿฌ ๋ฒˆ ๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•œ iterables์€ @@iterator ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ๋งค ํšŒ ์ƒˆ๋กœ์šด iterator๋ฅผ ๋ฐ˜๋“œ์‹œ ๋ฐ˜ํ™˜ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž ์ •์˜ iterable

์ด์™€ ๊ฐ™์ด ์ž์‹ ์˜ ๋ฐ˜๋ณต๊ฐ€๋Šฅ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

javascript
    var myIterable = {
        *[Symbol.iterator]() {
            yield 1;
            yield 2;
            yield 3;
        }
    }

    for (let value of myIterable) {
        console.log(value);
    }
    // 1
    // 2
    // 3

    or

    [...myIterable]; // [1, 2, 3]

๋‚ด์žฅ iterable

String, Array, TypedArray, Map ๋ฐ Set์€ ๋ชจ๋‘ ๋‚ด์žฅ ๋ฐ˜๋ณต๊ฐ€๋Šฅ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค, ๊ทธ๋“ค์˜ ํ”„๋กœํ† ํƒ€์ž… ๊ฐ์ฒด๊ฐ€ ๋ชจ๋‘ Symbol.iterator ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

iterable์„ ๊ธฐ๋Œ€ํ•˜๋Š” ๊ตฌ๋ฌธ

์ผ๋ถ€ ๋ฌธ(statement) ๋ฐ ์‹(expression)์€ iterableํ•ฉ๋‹ˆ๋‹ค, ๊ฐ€๋ น for-of ๋ฃจํ”„, spread syntax, yield* ๋ฐ ํ•ด์ฒด ํ• ๋‹น.

js
for (let value of ["a", "b", "c"]) {
  console.log(value);
}
// "a"
// "b"
// "c"

[..."abc"]; // ["a", "b", "c"]

function* gen() {
  yield* ["a", "b", "c"];
}

gen().next(); // { value:"a", done:false }

[a, b, c] = new Set(["a", "b", "c"]);
a; // "a"

Generator ์‹ฌํ™”

์ƒ์„ฑ์ž ํ•จ์ˆ˜๋Š” ์š”์ฒญ์— ๋”ฐ๋ผ ๊ทธ ์‚ฐ์ถœ๋œ(yielded, yield ์‹์œผ๋กœ ์‚ฐ์ถœ๋œ) ๊ฐ’์„ ๊ณ„์‚ฐํ•˜๊ณ , ๊ณ„์‚ฐํ•˜๊ธฐ ๋น„์‹ผ(ํž˜๋“ ) ์ˆ˜์—ด ๋˜๋Š” ์œ„์— ์„ค๋ช…ํ•œ ๋Œ€๋กœ ๋ฌดํ•œ ์ˆ˜์—ด์ด๋ผ๋„ ํšจ์œจ์ ์œผ๋กœ ๋‚˜ํƒ€๋‚ด๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

next() ๋ฉ”์„œ๋“œ๋Š” ๋˜ํ•œ ์ƒ์„ฑ๊ธฐ์˜ ๋‚ด๋ถ€ ์ƒํƒœ๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๋ฐ ์“ฐ์ผ ์ˆ˜ ์žˆ๋Š” ๊ฐ’์„ ๋ฐ›์Šต๋‹ˆ๋‹ค. next()์— ์ „๋‹ฌ๋˜๋Š” ๊ฐ’์€ ์ƒ์„ฑ๊ธฐ๊ฐ€ ์ค‘๋‹จ๋œ ๋งˆ์ง€๋ง‰ yield ์‹์˜ ๊ฒฐ๊ณผ๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ sequence(์ˆ˜์—ด)์„ ์žฌ์‹œ์ž‘ํ•˜๊ธฐ ์œ„ํ•ด next(x)๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ”ผ๋ณด๋‚˜์น˜ ์ƒ์„ฑ๊ธฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค:

js
function* fibonacci() {
  var fn1 = 0;
  var fn2 = 1;
  while (true) {
    var current = fn1;
    fn1 = fn2;
    fn2 = current + fn1;
    var reset = yield current;
    if (reset) {
      fn1 = 0;
      fn2 = 1;
    }
  }
}

var sequence = fibonacci();
console.log(sequence.next().value); // 0
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 2
console.log(sequence.next().value); // 3
console.log(sequence.next().value); // 5
console.log(sequence.next().value); // 8
console.log(sequence.next(true).value); // 0
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 2

์ œ๋„ˆ๋ ˆ์ดํ„ฐ์˜ throw() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  throwํ•ด์•ผ ํ•˜๋Š” ์˜ˆ์™ธ ๊ฐ’์„ ์ „๋‹ฌํ•˜์—ฌ ์ƒ์„ฑ์ž๊ฐ€ ์˜ˆ์™ธ๋ฅผ throwํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์˜ˆ์™ธ๋Š” ์ƒ์„ฑ๊ธฐ์˜ ํ˜„์žฌ ์ผ์‹œ ์ค‘๋‹จ๋œ ์ปจํ…์ŠคํŠธ์—์„œ throw๋ฉ๋‹ˆ๋‹ค. ๋งˆ์น˜ ํ˜„์žฌ ์ผ์‹œ ์ค‘๋‹จ๋œ yield ๊ฐ€ ๋Œ€์‹  throwvalue ๋ฌธ์ธ ๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ž…๋‹ˆ๋‹ค.

์˜ˆ์™ธ๊ฐ€ ์ƒ์„ฑ๊ธฐ ๋‚ด์—์„œ ํฌ์ฐฉ๋˜์ง€ ์•Š์œผ๋ฉด throw() ํ˜ธ์ถœ์„ ํ†ตํ•ด ์ „ํŒŒ๋˜๊ณ  ์ดํ›„์˜ next() ํ˜ธ์ถœ์€ done ์†์„ฑ์ด true ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

์ œ๋„ˆ๋ ˆ์ดํ„ฐ์—๋Š” ์ฃผ์–ด์ง„ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ์ž์ฒด๋ฅผ ์™„๋ฃŒํ•˜๋Š” return(value) ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.