๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Essays

[JavaScript] iterable ์‰ฝ๊ฒŒ ์ดํ•ดํ•˜๊ธฐ

by VincentKim 2023. 4. 17.

https://www.yankodesign.com/2022/12/28/this-sleek-inception-top-is-a-world-record-setting-toy-that-spins-for-more-than-4-hours/

 

 

๐Ÿ‘ถ๐Ÿป์‹œ์ž‘ํ•˜๊ธฐ ์ „์— 

์ฒ˜์Œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ผ๋Š” ๊ฐœ๋…์„ ์ ‘ํ–ˆ์„ ๋•Œ '์–ด๋ ต๋‹ค' ๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๋˜ ๊ธฐ์–ต์ด ์žˆ์Šต๋‹ˆ๋‹ค. [Symbol.iterator] ๋ผ๋Š” ๊ฒƒ์„ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ํ•œ๋‹ค๋Š”๋ฐ ์ €๊ฒŒ ๋ฌด์Šจ ๋ฌธ๋ฒ•์ธ์ง€ ๋ชจ๋ฅด๊ฒ ๊ณ , ํ˜ผ๋ž€์Šค๋Ÿฌ์› ๋˜ ๊ธฐ์–ต์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ค๋Š˜์€ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ์— ๋Œ€ํ•ด ์นผ๋Ÿผ์„ ์ž‘์„ฑํ•˜๊ธฐ ์ด์ „์— ์ดํ„ฐ๋ ˆ์ดํ„ฐ ๊ฐœ๋…์— ๋Œ€ํ•ด ์กฐ๊ธˆ ๋” ์‰ฝ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š” ๊ธ€์„ ์ž‘์„ฑํ•ด ๋ณด๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ ์–ด๋ ต์ง€ ์•Š์œผ๋‹ˆ ํ•จ๊ป˜ ๊ฐ€๋ด…์‹œ๋‹ค! 

 

 

ES6์™€ ์ดํ„ฐ๋Ÿฌ๋ธ”

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ES6 ์ด์ „์˜ ์ˆœํšŒ ๊ฐ€๋Šฅํ•œ ์ž๋ฃŒ๊ตฌ์กฐ๋“ค์€ ํ†ต์ผ๋œ ๊ทœ์•ฝ ์—†์ด ๊ฐ์ž ๋‚˜๋ฆ„์˜ ๋…๋ฆฝ์ ์ธ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์ˆœํšŒ๋ฅผ ํ–ˆ์—ˆ์Šต๋‹ˆ๋‹ค.  ES6 ์—์„œ๋Š” ์ˆœํšŒ ๊ฐ€๋Šฅํ•œ ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ”์ดํ„ฐ๋Ÿฌ๋ธ”"๋กœ ํ†ต์ผํ•˜์—ฌ ์ผ์›ํ™” ํ•˜์˜€๊ณ , ๊ทธ๋ฆฌํ•˜์—ฌ for…of ๋ฌธ, ์Šคํ”„๋ ˆ๋“œ ๋ฌธ๋ฒ•, ๋ฐฐ์—ด ๋””์ŠคํŠธ๋Ÿญ์ฒ˜๋ง ํ• ๋‹น์˜ ๋Œ€์ƒ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜์˜€์Šต๋‹ˆ๋‹ค. 

 

 

์ดํ„ฐ๋Ÿฌ๋ธ”๊ณผ ์ดํ„ฐ๋ ˆ์ด์…˜ ๊ทธ๋ฆฌ๊ณ  ์ดํ„ฐ๋ ˆ์ด์…˜ ํ”„๋กœํ† ์ฝœ 

๊ฐ„๋‹จํ•˜๊ฒŒ ๋งํ•ด ์ดํ„ฐ๋Ÿฌ๋ธ”๊ณผ ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. ๊ทผ๋ฐ ๊ทธ๋ƒฅ ๊ฐ์ฒด๊ฐ€ ์•„๋‹ˆ๋ผ ์ˆœํšŒ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด ํŠน์ •ํ•œ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋„๋ก ๋งŒ๋“  ๊ฐ์ฒด์ด์ฃ . ๊ทธ๋ฆฌ๊ณ  ์–ด๋–ค ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“ค์–ด์•ผ '์ด๋Ÿฌ๋Ÿฌ๋ธ”', '์ดํ„ฐ๋ ˆ์ดํ„ฐ' ๋ผ๊ณ  ๋ถ€๋ฅผ ์ˆ˜ ์žˆ๋Š”์ง€ ๊ทœ์•ฝ์œผ๋กœ ์ •ํ•ด ๋‘์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ทœ์•ฝ์ด๋ผ๋Š” ๊ฒƒ์€ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งํ•ด  '์–ด๋– ํ•œ ํ•จ์ˆ˜๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ , ์–ด๋– ํ•œ ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ํ•œ๋‹ค' ๋ผ๊ณ  ์ •ํ•ด๋†“์€ ์•ฝ์†์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด ์•ฝ์†์„ ์šฐ๋ฆฌ๋Š” "์ดํ„ฐ๋Ÿฌ๋ธ” ํ”„๋กœํ† ์ฝœ" ๊ณผ "์ดํ„ฐ๋ ˆ์ดํ„ฐ ํ”„๋กœํ† ์ฝœ"์ด๋ผ๊ณ  ๋ถ€๋ฅด๊ธฐ๋กœ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์–ด๋–ค ๊ฐ์ฒด๊ฐ€ ์ดํ„ฐ๋ ˆ์ด์…˜ ํ”„๋กœํ† ์ฝœ์„ ๊ตฌํ˜„ํ•œ๋‹ค๋ผ๋Š” ๊ฒƒ์€ ์ดํ„ฐ๋Ÿฌ๋ธ” ํ”„๋กœํ† ์ฝœ์„ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. 

 

 

์ดํ„ฐ๋Ÿฌ๋ธ” ํ”„๋กœํ† ์ฝœ

์–ด๋– ํ•œ ๊ฐ์ฒด๊ฐ€ ์ดํ„ฐ๋Ÿฌ๋ธ”์ด ๋˜๊ธฐ ์œ„ํ•ด์„œ๋Š” (1) [Symbol.iterator]๋ฅผ ๊ฐ์ฒด ๋‚ด์— key๋กœ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ํ•˜๋ฉฐ (2) [Symbol.iterator]()  ๋Š” ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. 

 

const iterableObj = {
	Symbol.iterator: function() {
    return iteratorObj
  }
}

 

์ด๋Ÿฐ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒƒ์ด์ง€์š”. Symbol.iterator๋Š” ๊ฐ์ฒด์˜ key์ด๋ฉฐ ๋Œ€๊ด„ํ˜ธ ํ‘œ๊ธฐ๋ฒ•์œผ๋กœ ๊ฐ์ฒด์˜ ํ‚ค์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ•ด๋‹น ํ‚ค์˜ value๋กœ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๋ฐ์š”, ์ด ๋ฉ”์„œ๋“œ๋Š” ์‹คํ–‰์‹œ iterator ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. 

์ •๋ฆฌํ•˜๋ฉด ์ดํ„ฐ๋Ÿฌ๋ธ”์ด๋ž€ Symbol.iterator ๋ผ๋Š” ํ‚ค์— ์ดํ„ฐ๋Ÿฌ๋ธ”์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๊ฐ’์œผ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. ์ดํ„ฐ๋Ÿฌ๋ธ” ๊ฐ์ฒด๋Š” ์ด๋Ÿฐ ์กฐ๊ฑด์„ ๊ฐ–์ถ”์–ด์•ผ ํ•˜๊ณ  ์ด๋ฅผ ์ดํ„ฐ๋Ÿฌ๋ธ” ํ”„๋กœํ† ์ฝœ์ด๋ผ ๋ถ€๋ฅด๋Š” ๊ฒƒ์ด์ง€์š”. 

 

 

์ดํ„ฐ๋ ˆ์ดํ„ฐ ํ”„๋กœํ† ์ฝœ 

๋ฐ”๋กœ ์ „ ์˜ˆ์ œ์—์„œ ์ดํ„ฐ๋Ÿฌ๋ธ”์€ ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๊ฐ’์œผ๋กœ ํ•˜๋Š” Symbol.iterator ๋ผ๋Š” ํ‚ค๊ฐ’์œผ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฐ์ฒด์ž„์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ๋ฐ˜ํ™˜๋˜๋Š” ์ดํ„ฐ๋ ˆ์ดํ„ฐ ๊ฐ์ฒด๋Š” next() ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด next() ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด IteratorResult ๋ผ๋Š” ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. IteratorResult ๊ฐ์ฒด๋Š” value์™€ done ์ด๋ผ๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด ์ˆœํ™˜์ด ๋๋‚ฌ๋Š”์ง€๋ฅผ ์•Œ ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.  

 

 

์ดํ„ฐ๋Ÿฌ๋ธ” ๋ˆˆ์œผ๋กœ ํ™•์ธํ•˜๊ธฐ 

์ง€๊ธˆ๊นŒ์ง€ ์ดํ„ฐ๋Ÿฌ๋ธ”, ์ดํ„ฐ๋ ˆ์ดํ„ฐ๊ฐ€ ๋˜๊ธฐ ์œ„ํ•ด ๊ฐ–์ถ”์–ด์•ผ ํ•  ์กฐ๊ฑด์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ถ”์ƒ์ ์ด๊ฒŒ ๋Š๊ปด์ง€๋‚˜์š”? ์ด๋ฒˆ์—๋Š” ๋ˆˆ์œผ๋กœ ํ™•์ธํ•˜๋ฉฐ ์กฐ๊ธˆ ๋” ์ง๊ด€์ ์œผ๋กœ ์ดํ•ดํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. 

 

//(1)
const iteratorFn = Array.prototype[Symbol.iterator];
console.log(iteratorFn); //[Function: values]

//(2)
const iteratorObj = Array.prototype[Symbol.iterator]();
console.log(iteratorObj); //Object [Array Iterator] {}

 

 

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๋นŒํŠธ์ธ ๊ฐ์ฒด์ธ Array๋Š” ์ดํ„ฐ๋ ˆ์ด์…˜ ํ”„๋กœํ† ์ฝœ์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๋ชจ๋“  ๋ฐฐ์—ด์€ ์ดํ„ฐ๋Ÿฌ๋ธ” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. ์œ„ ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด [Symbol.iterator] ๋Š” ํ•จ์ˆ˜์ด๋ฉฐ [Symbol.iterator]()๋Š” ๊ทธ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•œ ๊ฒƒ์ด์ฃ . ๊ทธ ๊ฒฐ๊ณผ ๋ณ€์ˆ˜ iteratorFn ์—๋Š” ํ•จ์ˆ˜๊ฐ€ ํ• ๋‹น๋˜๋ฉฐ, iteratorObj ์—๋Š” ์ด ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ๋ฐ˜ํ™˜๋œ ์ดํ„ฐ๋ ˆ์ดํ„ฐ๊ฐ€ ํ• ๋‹น๋˜์ฃ . ๋ฌผ๋ก  iteratorObj ๋Š” next() ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ฒ ์ง€์š”? 

 

 

Iterator ์‚ฌ์šฉํ•ด ๋ณด๊ธฐ

 

 

const arr = [1, 2, 3];
const iteratorObject = arr[Symbol.iterator]();

//(1) next(...args: [] | [TNext]): IteratorResult<T, TReturn>;

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

 

 

์œ„ ์˜ˆ์ œ์—์„œ๋Š” ์ดํ„ฐ๋ ˆ์ดํ„ฐ๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” next() ๋ฉ”์„œ๋“œ๋ฅผ ํ™œ์šฉํ•ด์„œ ๊ฐ’์„ ์ˆœํšŒํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ฃผ์„์œผ๋กœ ์ฒ˜๋ฆฌ๋œ ๋ถ€๋ถ„์— ๋ณด์‹œ๋ฉด next() ๋ฉ”์„œ๋“œ๋Š” IteratorResult๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.( ์ œ๋„ค๋ฆญ๊ณผ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์— ์ต์ˆ™ํ•˜์ง€ ์•Š๋‹ค๋ฉด ๋„˜์–ด๊ฐ€๋„ ์ข‹์Šต๋‹ˆ๋‹ค. ) ์ด๋ ‡๊ฒŒ ๋ฐ˜ํ™˜๋œ ๊ฐ์ฒด๋Š” value์™€ done์„ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ for...of ์™€ ๊ฐ™์ด ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ ํ™œ์šฉํ•ด์„œ ๊ฐ’์„ ์ˆœํšŒํ•˜๋Š” ๋ฌธ๋ฒ•์€ ์ด๋ฅผ ์ด์šฉํ•ด ๊ฐ’์„ ์ˆœํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

 

for...of ๋Š” ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ• ๊นŒ?

 

 

const array = [1,2,3];
const iterator = array.values(); //values(): IterableIterator<T>;

while (true) { //(1)
  const item = iterator.next();
  if (item.done) break;
  console.log(item.value); // 1 2 3
}

for (let item of array) { //(2)
  console.log(item);
}

 

for of๋ฌธ์€ ์•„๋งˆ๋„ ๋‚ด๋ถ€์ ์œผ๋กœ (1)๊ณผ ๊ฐ™์ด ๊ตฌํ˜„๋˜์–ด ์žˆ์œผ๋ฆฌ๋ผ ์ถ”์ธกํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. done์ด true๊ฐ€ ๋  ๋•Œ๊นŒ์ง€ value๋ฅผ ์ˆœํšŒํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” (2)์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ์ดํ„ฐ๋ ˆ์ดํ„ฐ์˜ next() ๋ฉ”์„œ๋“œ์™€ ๊ทธ ๊ฒฐ๊ณผ๊ฐ’์ธ IteratorResult ๊ฐ์ฒด๋ฅผ ํ™œ์šฉํ•ด์„œ ์ˆœํšŒ๋ฅผ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. 

 

 

์ •๋ฆฌํ•ฉ์‹œ๋‹ค. 

์ดํ„ฐ๋Ÿฌ๋ธ”, ์ดํ„ฐ๋ ˆ์ดํ„ฐ์— ๋Œ€ํ•ด ๊ฐ„๋‹จํžˆ ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์‰ฝ๊ฒŒ ํ•ต์‹ฌ๋งŒ ์ „๋‹ฌํ•˜๋Š”๋ฐ ์ดˆ์ ์„ ๋งž์ถ”์—ˆ๊ธฐ์—, ์ด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋” ์ž์„ธํ•œ ๊ธ€์„ ์ฐพ์•„๋ณด์‹œ๋ฉด ์ดํ•ดํ•˜๋Š”๋ฐ ๋„์›€์ด ๋˜๋ฆฌ๋ผ๋Š” ์ƒ๊ฐ์—์„œ ๊ธ€์„ ๊ฒฐ์‹ฌํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค : )

 

 

 

 

 

 

๋Œ“๊ธ€