๐Ÿ“– ์ดํ„ฐ๋Ÿฌ๋ธ”

c_yjยท2022๋…„ 7์›” 13์ผ
0

DeepDive

๋ชฉ๋ก ๋ณด๊ธฐ
31/42
post-thumbnail

์ดํ„ฐ๋ ˆ์ด์…˜ ํ”„๋กœํ† ์ฝœ โ“

ES6์—์„œ ๋„์ž…๋œ ์ดํ„ฐ๋ ˆ์ด์…˜ ํ”„๋กœํ† ์ฝœ์€ ์ˆœํšŒ ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ ์ปฌ๋ ‰์…˜์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ECMAScript ์‚ฌ์–‘์— ์ •์˜ํ•˜์—ฌ ๋ฏธ๋ฆฌ ์•ฝ์†ํ•œ ๊ทœ์น™์ด๋‹ค.

์ดํ„ฐ๋Ÿฌ๋ธ” โ”

์ดํ„ฐ๋Ÿฌ๋ธ” ํ”„๋กœํ† ์ฝœ์„ ์ค€์ˆ˜ํ•œ ๊ฐ์ฒด๋ฅผ ์ดํ„ฐ๋Ÿฌ๋ธ”์ด๋ผ ํ•œ๋‹ค. ์ดํ„ฐ๋Ÿฌ๋ธ”์€ Symbol.iterator๋ฅผ ํ”„๋กœํผํ‹ฐ ํ‚ค๋กœ ์‚ฌ์šฉํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ์ง์ ‘ ๊ตฌํ˜„ํ•˜๊ฑฐ๋‚˜ ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ์„ ํ†ตํ•ด ์ƒ์†๋ฐ›์€ ๊ฐ์ฒด๋ฅผ ๋งํ•œ๋‹ค.

์ดํ„ฐ๋Ÿฌ๋ธ”์ธ์ง€ ํ™•์ธํ•˜๋Š” ํ•จ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌํ˜„

const isIterable = v => v !== null && typeof v[Symbol.iterator] === 'function';

// ๋ฐฐ์—ด, ๋ฌธ์ž์—ด, Map, Set ๋“ฑ์€ ์ดํ„ฐ๋Ÿฌ๋ธ”์ด๋‹ค.
isIterable([]); // true
isIterable(''); // true
isIterable(new Map()); // true
isIterable(new Set()); // true
isIterable(new Set()); // true
isIterable({}); // false

์ดํ„ฐ๋ ˆ์ดํ„ฐ โ”

์ดํ„ฐ๋Ÿฌ๋ธ”์˜ Symbol.iterator ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ดํ„ฐ๋ ˆ์ดํ„ฐ ํ”„๋กœํ† ์ฝœ์„ ์ค€์ˆ˜ํ•œ ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์ดํ„ฐ๋Ÿฌ๋ธ”์˜ Symbol.iterator ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฐ˜ํ™˜ํ•œ ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋Š” next ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ–๋Š”๋‹ค.

// ๋ฐฐ์—ด์€ ์ดํ„ฐ๋Ÿฌ๋ธ” ํ”„๋กœํ† ์ฝœ์„ ์ค€์ˆ˜ํ•œ ์ดํ„ฐ๋Ÿฌ๋ธ”์ด๋‹ค.
const array = [1,2,3];

// Symbol.iterator ๋ฉ”์„œ๋“œ๋Š” ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
const iterator = array[Symbol.iterator]();

// Symbol.iterator ๋ฉ”์„œ๋“œ๊ฐ€ ๋ด”ํ™˜ํ•œ ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋Š” next ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ–๋Š”๋‹ค.
console.log('next' in iterator); // true

์ดํ„ฐ๋ ˆ์ดํ„ฐ์˜ next ๋ฉ”์„œ๋“œ๋Š” ์ดํ„ฐ๋Ÿฌ๋ธ”์˜ ๊ฐ ์š”์†Œ๋ฅผ ์ˆœํšŒํ•˜๊ธฐ ์œ„ํ•œ ํฌ์ธํ„ฐ์˜ ์—ญํ• ์„ ํ•œ๋‹ค. ์ฆ‰ next ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ดํ„ฐ๋Ÿฌ๋ธ”์„ ์ˆœ์ฐจ์ ์œผ๋กœ ํ•œ ๋‹จ๊ฒŒ์”ฉ ์ˆœํšŒํ•˜๋ฉฐ ์ˆœํšŒ ๊ฒฐ๊ณผ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ดํ„ฐ๋ ˆ์ดํ„ฐ ๋ฆฌ์ ˆํŠธ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜

์ดํ„ฐ๋ ˆ์ดํ„ฐ์˜ next ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ดํ„ฐ๋ ˆ์ดํ„ฐ ๋ฆฌ์ ˆํŠธ ๊ฐ์ฒด์˜ value ํ”„๋กœํผํ‹ฐ๋Š” ํ˜„์žฌ ์ˆœํšŒ ์ค‘์ธ ์ดํ„ฐ๋Ÿฌ๋ธ”์˜ ๊ฐ’์„ ๋‚˜ํƒ€๋‚ด๋ฉฐ done ํ”„๋กœํผํ‹ฐ๋Š” ์ดํ„ฐ๋Ÿฌ๋ธ”์˜ ์ˆœํšŒ ์™„๋ฃŒ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.

๋นŒํŠธ์ธ ํ”„๋กœํ† ์ฝœ โ“

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์ดํ„ฐ๋ ˆ์ด์…˜ ํ”„๋กœํ† ์ฝœ์„ ์ค€์ˆ˜ํ•œ ๊ฐ์ฒด์ธ ๋นŒํŠธ์ธ ์ดํ„ฐ๋Ÿฌ๋ธ”์„ ์ œ๊ณตํ•œ๋‹ค. ๋‹ค์Œ์˜ ํ‘œ์ค€ ๋นŒํŠธ์ธ ๊ฐ์ฒด๋“ค์€ ๋นŒํŠธ์ธ ์ดํ„ฐ๋Ÿฌ๋ธ”์ด๋‹ค.

for... of ๋ฌธ โ“

for.. of ๋ฌธ์€ ์ดํ„ฐ๋Ÿฌ๋ธ”์„ ์ˆœํšŒํ™”๋ฉด์„œ ์ดํ„ฐ๋Ÿฌ๋ธ”์˜ ์š”์†Œ๋ฅผ ๋ณ€์ˆ˜์— ํ• ๋‹นํ•œ๋‹ค.

for (๋ณ€์ˆ˜์„ ์–ธ๋ฌธ of ์ดํ„ฐ๋Ÿฌ๋ธ”) {...}

for...of ๋ฌธ์€ for..in ๋ฌธ์˜ ํ˜•์‹๊ณผ ๋งค์šฐ ์œ ์‚ฌ

for (๋ณ€์ˆ˜์„ ์–ธ๋ฌธ in ๊ฐ์ฒด) {...}

for... in๋ฌธ์€ ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ ์ƒ์— ์กด์žฌํ•˜๋Š” ๋ชจ๋“  ํ”„๋กœํ† ํƒ€์ž…์˜ ํ”„๋กœํผํ‹ฐ ์ค‘์—์„œ ํ”„๋กœํผํ‹ฐ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ [[Enumerable]]์˜ ๊ฐ’์ด true์ธ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ ์—ด๊ฑฐํ•œ๋‹ค. ์ด๋•Œ ํ”„๋กœํผํ‹ฐ ํ‚ค๊ฐ€ ์‹ฌ๋ฒŒ์ธ ํ”„๋กœํผํ‹ฐ๋Š” ์—ด๊ฑฐํ•˜์ง€ ์•Š๋Š”๋‹ค.

for...of ๋ฌธ์€ ๋‚ด๋ถ€์ ์œผ๋กœ ์ดํ„ฐ๋ ˆ์ดํ„ฐ์˜ next ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ดํ„ฐ๋Ÿฌ๋ธ”์„ ์ˆœํšŒํ•˜๋ฉฐ next ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฐ˜ํ™˜ํ•œ ์ดํ„ฐ๋ ˆ์ดํ„ฐ ๋ฆฌ์ ˆํŠธ ๊ฐ์ฒด์˜ value ํ”„๋กœํผํ‹ฐ ๊ฐ’์„ for...of ๋ฌธ์˜ ๋ณ€์ˆ˜์— ํ• ๋‹น.๊ทธ๋ฆฌ๊ณ  ์ดํ„ฐ๋ ˆ์ดํ„ฐ ๋ฆฌ์ ˆํŠธ ๊ฐ์ฒด์˜ done ํ”„๋กœํผํ‹ฐ ๊ฐ’์ด false ์ด๋ฉด ์ดํ„ฐ๋Ÿฌ๋ธ”์˜ ์ˆœํšŒ๋ฅผ ๊ณ„์†ํ•˜๊ณ  true์ด๋ฉด ์ดํ„ฐ๋Ÿฌ๋ธ”์˜ ์ˆœํšŒ๋ฅผ ์ค‘๋‹จํ•œ๋‹ค.

for (const item of [1, 2, 3]) {
  // item ๋ณ€์ˆ˜์— ์ˆœ์ฐจ์ ์œผ๋กœ 1, 2, 3์ด ํ• ๋‹น๋œ๋‹ค.
  console.log(item); // 1 2 3
}

์ดํ„ฐ๋Ÿฌ๋ธ”๊ณผ ์œ ์‚ฌ ๋ฐฐ์—ด ๊ฐ์ฒด โ“

์œ ์‚ฌ ๋ฐฐ์—ด ๊ฐ์ฒด๋Š” ๋งˆ์น˜ ๋ฐฐ์—ด์ฒ˜๋Ÿผ ์ธ๋ฑ์Šค๋กœ ํ”„๋กœํผํ‹ฐ ๊ฐ’์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ณ  length ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ–๋Š” ๊ฐ์ฒด๋ฅผ ๋งํ•œ๋‹ค. ์œ ์‚ฌ ๋ฐฐ์—ด ๊ฐ์ฒด๋Š” length ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ–๊ธฐ ๋–„๋ฌธ์— for ๋ฌธ์œผ๋กœ ์ˆœํšŒํ•  ์ˆ˜ ์žˆ๊ณ , ์ธ๋ฑ์Šค๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ˆซ์ž ํ˜•์‹์˜ ๋ฌธ์ž์—ด์„ ํ”„๋กœํผํ‹ฐ ํ‚ค๋กœ, ๊ฐ€์ง€๋ฏ€๋กœ ๋งˆ์น˜ ๋ฐฐ์—ด์ฒ˜๋Ÿผ ์ธ๋ฑ์Šค๋กœ ํ”„๋กœํผํ‹ฐ ๊ฐ’์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

์œ ์‚ฌ ๋ฐฐ์—ด ๊ฐ์ฒด๋Š” ์ดํ„ฐ๋Ÿฌ๋ธ”์ด ์•„๋‹Œ ์ผ๋ฐ˜ ๊ฐ์ฒด๋‹ค. ๋”ฐ๋ผ์„œ ์œ ์‚ฌ ๋ฐฐ์—ด ๊ฐ์ฒด์—๋Š” Symbol.iterator ๋ฉ”์„œ๋“œ๊ฐ€ ์—†๊ธฐ ๋–„๋ฌธ์— for...of ๋ฌธ์œผ๋กœ ์ˆœํšŒํ•  ์ˆ˜ ์—†๋‹ค.

ES6์—์„œ ์ดํ„ฐ๋Ÿฌ๋ธ”์ด ๋„์ž…๋˜๋ฉด์„œ ์œ ์‚ฌ ๋ฐฐ์—ด ๊ฐ์ฒด์ธ arguments, NodeList, HTMLCollection ๊ฐ์ฒด์— Symbol.iterator ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ ์ดํ„ฐ๋Ÿฌ๋ธ”์ด ๋˜์—ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ดํ„ฐ๋Ÿฌ๋ธ”์ด ๋œ ์ดํ›„์—๋„ length ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง€๋ฉฐ ์ธ๋ฑ์Šค๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์—๋Š” ๋ณ€ํ•จ์ด ์—†์œผ๋ฏ€๋กœ ์œ ์‚ฌ ๋ฐฐ์—ด ๊ฐ์ฒด์ด๋ฉด์„œ ์ดํ„ฐ๋Ÿฌ๋ธ”์ธ ๊ฒƒ์ด๋‹ค.

์ดํ„ฐ๋ ˆ์ด์…˜ ํ”„๋กœํ† ์ฝœ์˜ ์ค‘์š”์„ฑ โ“

์ดํ„ฐ๋ ˆ์ด์…˜ ํ”„๋กœํ† ์ฝœ์€ ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ๊ณต๊ธ‰์ž๊ฐ€ ํ•˜๋‚˜์˜ ์ˆœํšŒ ๋ฐฉ์‹์„ ๊ฐ–๋„๋ก ๊ทœ์ •ํ•˜์—ฌ ๋ฐ์ดํ„ฐ ์†Œ๋น„์ž๊ฐ€ ํšจ์œจ์ ์œผ๋กœ ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ๊ณต๊ธ‰์ž๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฐ์ดํ„ฐ ์†Œ๋น„์ž์™€ ๋ฐ์ดํ„ฐ ๊ณต๊ธ‰์ž๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค์˜ ์—ญํ• ์„ ํ•œ๋‹ค.

์‚ฌ์šฉ์ž ์ •์˜ ์ดํ„ฐ๋Ÿฌ๋ธ” โ“

์‚ฌ์šฉ์ž ์ •์˜ ์ดํ„ฐ๋Ÿฌ๋ธ” ๊ตฌํ˜„ โ”

์ดํ„ฐ๋ ˆ์ด์…˜ ํ”„๋กœํ† ์ฝœ์„ ์ค€์ˆ˜ํ•˜์ง€ ์•Š๋Š” ์ผ๋ฐ˜ ๊ฐ์ฒด๋„ ์ดํ„ฐ๋ ˆ์ด์…˜ ํ”„๋กœํ† ์ฝœ์„ ์ค€์ˆ˜ํ•˜๋„๋ก ๊ตฌํ˜„ํ•˜๋ฉด ์‚ฌ์šฉ์ž ์ •์˜ ์ดํ„ฐ๋Ÿฌ๋ธ”์ด ๋œ๋‹ค.

// ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์„ ๊ตฌํ˜„ํ•œ ์‚ฌ์šฉ์ž ์ •์˜ ์ดํ„ฐ๋Ÿฌ๋ธ”
const fibonacci = {
  // Symbol.iterator ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ ์ดํ„ฐ๋Ÿฌ๋ธ” ํ”„๋กœํ† ์ฝœ์„ ์ค€์ˆ˜ํ•œ๋‹ค.
  [Symbol.iterator]() {
    let [pre, cur] = [0, 1]; // "36.1. ๋ฐฐ์—ด ๋””์ŠคํŠธ๋Ÿญ์ฒ˜๋ง ํ• ๋‹น" ์ฐธ๊ณ 
    const max = 10; // ์ˆ˜์—ด์˜ ์ตœ๋Œ€๊ฐ’

    // Symbol.iterator ๋ฉ”์„œ๋“œ๋Š” next ๋ฉ”์„œ๋“œ๋ฅผ ์†Œ์œ ํ•œ ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•˜๊ณ 
    // next ๋ฉ”์„œ๋“œ๋Š” ์ดํ„ฐ๋ ˆ์ดํ„ฐ ๋ฆฌ์ ˆํŠธ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•œ๋‹ค.
    return {
      next() {
        [pre, cur] = [cur, pre + cur]; // "36.1. ๋ฐฐ์—ด ๋””์ŠคํŠธ๋Ÿญ์ฒ˜๋ง ํ• ๋‹น" ์ฐธ๊ณ 
        // ์ดํ„ฐ๋ ˆ์ดํ„ฐ ๋ฆฌ์ ˆํŠธ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
        return { value: cur, done: cur >= max };
      }
    };
  }
};

// ์ดํ„ฐ๋Ÿฌ๋ธ”์ธ fibonacci ๊ฐ์ฒด๋ฅผ ์ˆœํšŒํ•  ๋•Œ๋งˆ๋‹ค next ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.
for (const num of fibonacci) {
  console.log(num); // 1 2 3 5 8
}

์‚ฌ์šฉ์ž ์ •์˜ ์ดํ„ฐ๋Ÿฌ๋ธ”์€ ์ดํ„ฐ๋ ˆ์ด์…˜ ํ”„๋กœํ† ์ฝœ์„ ์ค€์ˆ˜ํ•˜๋„๋ก Symbol.iterator ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  Symbol.iterator ๋ฉ”์„œ๋“œ๊ฐ€ next ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ–๋Š” ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ดํ„ฐ๋ ˆ์ดํ„ฐ์˜ next ๋ฉ”์„œ๋“œ๋Š” done๊ณผ value ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง€๋Š” ์ดํ„ฐ๋ ˆ์ดํ„ฐ ๋ฆฌ์ €ํŠธ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
for...of ๋ฌธ์€ done ํ”„๋กœํผํ‹ฐ๊ฐ€ true๊ฐ€ ๋  ๋–„๊นŒ์ง€ ๋ฐ˜๋ณตํ•˜๋ฉฐ done ํ”„๋กœํผํ‹ฐ๊ฐ€ true๊ฐ€ ๋˜๋ฉด ๋ฐ˜๋ณต์šธ ์ฆ์ง€
์ดํ„ฐ๋Ÿฌ๋ธ”์€ for...of ๋ฌธ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์Šคํ”„๋ ˆ๋“œ ๋ฌธ๋ฒ•, ๋ฐฐ์—ด ๋””์ŠคํŠธ๋Ÿญ์ฒ˜๋ง ํ• ๋‹น์—๋„ ์‚ฌ์šฉ

์ดํ„ฐ๋Ÿฌ๋ธ”์„ ์ƒ์„ฑํ•˜๋Š” ํ•จ์ˆ˜ โ”

์•ž์—์„œ ์‚ดํŽด๋ณธ fibonacci ์ดํ„ฐ๋Ÿฌ๋ธ”์€ ๋‚ด๋ถ€์— ์ˆ˜์—ด์˜ ์ตœ๋Œ€๊ฐ’ max๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ์ด ์ˆ˜์—ด์˜ ์ตœ๋Œ€๊ฐ’์€ ๊ณ ์ •๋œ ๊ฐ’์œผ๋กœ ์™ธ๋ถ€์—์„œ ์ „๋‹ฌํ•œ ๊ฐ’์œผ๋กœ ๋ณ€๊ฒฝํ•  ๋ฐฉ๋ฒ•์ด ์—†๋‹ค๋Š” ์•„์‰ฌ์›€์ด ์žˆ๋‹ค. ์ˆ˜์—ด์ด ์ตœ๋Œ€๊ฐ’์„ ์ธใ……๋กœ ์ „๋‹ฌ๋ฐ›์•„ ์ดํ„ฐ๋Ÿฌ๋ธ”์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด ๋ณด์ž.

// ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์„ ๊ตฌํ˜„ํ•œ ์‚ฌ์šฉ์ž ์ •์˜ ์ดํ„ฐ๋Ÿฌ๋ธ”์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜. ์ˆ˜์—ด์˜ ์ตœ๋Œ€๊ฐ’์„ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›๋Š”๋‹ค.
const fibonacciFunc = function (max) {
  let [pre, cur] = [0, 1];

  // Symbol.iterator ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•œ ์ดํ„ฐ๋Ÿฌ๋ธ”์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  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
}

์ดํ„ฐ๋Ÿฌ๋ธ”์ด๋ฉด์„œ ์ดํ„ฐ๋ ˆ์ดํ„ฐ์ธ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํ•จ์ˆ˜ โ”

์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๋ ค๋ฉด ์ดํ„ฐ๋Ÿฌ๋ธ”์˜ Symbol.iterator ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค.

// fibonacciFunc ํ•จ์ˆ˜๋Š” ์ดํ„ฐ๋Ÿฌ๋ธ”์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
const iterable = fibonacciFunc(5);
// ์ดํ„ฐ๋Ÿฌ๋ธ”์˜ Symbol.iterator ๋ฉ”์„œ๋“œ๋Š” ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜
const iterator = iterable[Symbol.iterator]();

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:5, done:true}

์ดํ„ฐ๋Ÿฌ๋ธ”์ด๋ฉด์„œ ์ดํ„ฐ๋ ˆ์ดํ„ฐ์˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋ฉด Symbol.iterator ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค. ๋‹ค์Œ ๊ฐ์ฒด๋Š” Symbol.iterator ๋ฉ”์„œ๋“œ์™€ next ๋ฉ”์„œ๋“œ๋ฅผ ์†Œ์œ ํ•œ ์ดํ„ฐ๋Ÿฌ๋ธ”์ด๋ฉด์„œ ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋‹ค. Symbol.iterator ๋ฉ”์„œ๋“œ๋Š” this๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ next ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ–๋Š” ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜.

// ์ดํ„ฐ๋Ÿฌ๋ธ”์ด๋ฉด์„œ ์ดํ„ฐ๋ ˆ์ดํ„ฐ์ธ ๊ฐ์ฒด. ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” Symbol.iterator ๋ฉ”์„œ๋“œ์™€
// ์ดํ„ฐ๋ ˆ์ด์…˜ ๋ฆฌ์ ˆํŠธ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” next ๋ฉ”์„œ๋“œ๋ฅผ ์†Œ์œ ํ•œ๋‹ค.
{
  [Symbol.iterator]() { return this; },
  next() {
    return { value: any, done: boolean };
  }
}
// ์ดํ„ฐ๋Ÿฌ๋ธ”์ด๋ฉด์„œ ์ดํ„ฐ๋ ˆ์ดํ„ฐ์ธ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜
const fibonacciFunc = function (max) {
  let [pre, cur] = [0, 1];

  // Symbol.iterator ๋ฉ”์„œ๋“œ์™€ next ๋ฉ”์„œ๋“œ๋ฅผ ์†Œ์œ ํ•œ ์ดํ„ฐ๋Ÿฌ๋ธ”์ด๋ฉด์„œ ์ดํ„ฐ๋ ˆ์ดํ„ฐ์ธ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜
  return {
    [Symbol.iterator]() { return this; },
    // next ๋ฉ”์„œ๋“œ๋Š” ์ดํ„ฐ๋ ˆ์ดํ„ฐ ๋ฆฌ์ ˆํŠธ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜
    next() {
      [pre, cur] = [cur, pre + cur];
      return { value: cur, done: cur >= max };
    }
  };
};

// iter๋Š” ์ดํ„ฐ๋Ÿฌ๋ธ”์ด๋ฉด์„œ ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋‹ค.
let iter = fibonacciFunc(10);

// iter๋Š” ์ดํ„ฐ๋Ÿฌ๋ธ”์ด๋ฏ€๋กœ for...of ๋ฌธ์œผ๋กœ ์ˆœํšŒํ•  ์ˆ˜ ์žˆ๋‹ค.
for (const num of iter) {
  console.log(num); // 1 2 3 5 8
}

// iter๋Š” ์ดํ„ฐ๋Ÿฌ๋ธ”์ด๋ฉด์„œ ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋‹ค
iter = fibonacciFunc(10);

// iter๋Š” ์ดํ„ฐ๋ ˆ์ดํ„ฐ์ด๋ฏ€๋กœ ์ดํ„ฐ๋ ˆ์ด์…˜ ๋ฆฌ์ ˆํŠธ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” next ๋ฉ”์„œ๋“œ๋ฅผ ์†Œ์œ ํ•œ๋‹ค.
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 }

๋ฌดํ•œ ์ดํ„ฐ๋Ÿฌ๋ธ”๊ณผ ์ง€์—ฐ ํ‰๊ฐ€ โ”

๋ฌดํ•œ ์ดํ„ฐ๋Ÿฌ๋ธ”์„ ์ƒ์„ฑํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ๋ฌดํ•œ ์ˆ˜์—ด์„ ๊ฐ„๋‹จํžˆ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

// ๋ฌดํ•œ ์ดํ„ฐ๋Ÿฌ๋ธ”์„ ์ƒ์„ฑํ•˜๋Š” ํ•จ์ˆ˜
const fibonacciFunc = function () {
  let [pre, cur] = [0, 1];

  return {
    [Symbol.iterator]() { return this; },
    next() {
      [pre, cur] = [cur, pre + cur];
      // ๋ฌดํ•œ์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋ฏ€๋กœ done ํ”„๋กœํผํ‹ฐ๋ฅผ ์ƒ๋žตํ•œ๋‹ค.
      return { value: cur };
    }
  };
};

// fibonacciFunc ํ•จ์ˆ˜๋Š” ๋ฌดํ•œ ์ดํ„ฐ๋Ÿฌ๋ธ”์„ ์ƒ์„ฑํ•œ๋‹ค.
for (const num of fibonacciFunc()) {
  if (num > 10000) break;
  console.log(num); // 1 2 3 5 8...4181 6765
}

// ๋ฐฐ์—ด ๋””์ŠคํŠธ๋Ÿญ์ฒ˜๋ง ํ• ๋‹น์„ ํ†ตํ•ด ๋ฌดํ•œ ์ดํ„ฐ๋Ÿฌ๋ธ”์—์„œ 3๊ฐœ์˜ ์š”์†Œ๋งŒ ์ทจ๋“ํ•œ๋‹ค.
const [f1, f2, f3] = fibonacciFunc();
console.log(f1, f2, f3); // 1 2 3

์œ„ ์˜ˆ์ œ์˜ ์ดํ„ฐ๋Ÿฌ๋ธ”์€ ์ง€์—ฐ ํ‰๊ฐ€๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑ ์ง€์—ฐ ํ‰๊ฐ€๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ํ•„์š”ํ•œ ์‹œ์  ์ด์ „๊นŒ์ง€๋Š” ๋ฏธ๋ฆฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๋‹ค๊ฐ€ ๋ฐ์ดํ„ฐ๊ฐ€ ํ•„์š”ํ•œ ์‹œ์ ์ด ๋˜๋ฉด ๊ทธ๋•Œ์•ผ ๋น„๋กœ์†Œ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ธฐ๋ฒ•์ด๋‹ค. ์ฆ‰ ํ‰๊ฐ€ ๊ฒฐ๊ณผ๊ฐ€ ํ•„์š”ํ•  ๋•Œ๊นŒ์ง€ ํ‰๊ฐ€๋ฅผ ๋Šฆ์ถ”๋Š” ๊ธฐ๋ฒ•์ด ์ง€์—ฐ ํ‰๊ฐ€๋‹ค.
์ง€์—ฐ ํ‰๊ฐ€๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ถˆํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฏธ๋ฆฌ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ  ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ํ•„์š”ํ•œ ์ˆœ๊ฐ„์— ์ƒ์„ฑํ•˜๋ฏ€๋กœ ๋น ๋ฅธ ์‹คํ–‰ ์†๋„๋ฅผ ๊ธฐ๋Œ€ํ•  ์ˆ˜ ์žˆ๊ณ  ๋ถˆํ•„์š”ํ•œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์†Œ๋น„ํ•˜์ง€ ์•Š์œผ๋ฉฐ ๋ฌดํ•œ๋„ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.

profile
FrontEnd Developer

0๊ฐœ์˜ ๋Œ“๊ธ€