- 34.1 μ΄ν°λ μ΄μ νλ‘ν μ½
- 34.2 λΉνΈμΈ μ΄ν°λ¬λΈ
- 34.3 forβ¦ofλ¬Έ
- 34.4 μ΄ν°λ¬λΈκ³Ό μ μ¬ λ°°μ΄ κ°μ²΄
- 4.5 μ΄ν°λ μ΄μ νλ‘ν μ½μ νμμ±
- 34.6 μ¬μ©μ μ μ μ΄ν°λ¬λΈ
β μ΄ν°λ μ΄μ νλ‘ν μ½μ μν κ°λ₯ν (iterable) λ°μ΄ν° 컬λ μ (μλ£κ΅¬μ‘°)μ λ§λ€κΈ° μν΄ ECMAScript μ¬μμ μ μνμ¬ λ―Έλ¦¬ μ½μν κ·μΉ
- ES6μμλ μν κ°λ₯ν λ°μ΄ν°λ€μ μ΄ν°λ μ΄μ νλ‘ν μ½μ μ€μνλ μ΄ν°λ¬λΈλ‘ ν΅μΌνλ€.
πΏ μ΄ν°λ μ΄μ νλ‘ν μ½
- μ΄ν°λ¬λΈ νλ‘ν μ½
- μ΄ν°λ¬λΈ νλ‘ν μ½μ μ€μν κ°μ²΄λ₯Ό μ΄ν°λ¬λΈμ΄λΌ νλ€. μ΄ν°λ¬λΈμ
forβ¦ofλ¬ΈμΌλ‘ μνν μ μμΌλ©° μ€νλ λ λ¬Έλ²κ³Ό λ°°μ΄ λμ€νΈλμ²λ§ ν λΉμ λμμΌλ‘ μ¬μ©ν μ μλ€.
- μ΄ν°λ¬λΈ νλ‘ν μ½μ μ€μν κ°μ²΄λ₯Ό μ΄ν°λ¬λΈμ΄λΌ νλ€. μ΄ν°λ¬λΈμ
- μ΄ν°λ μ΄ν° νλ‘ν μ½
- μ΄ν°λ μ΄ν° νλ‘ν μ½μ μ€μν κ°μ²΄λ₯Ό μ΄ν°λ μ΄ν°λΌ νλ€. μ΄ν°λ μ΄ν°λ μ΄ν°λ¬λΈμ μμλ₯Ό νμνκΈ° μν ν¬μΈν° μν μ νλ€.
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({}); // -> falseisIterableν¨μλ vκ° μ΄ν°λ¬λΈ κ°μ²΄μΈμ§ νμΈνλ ν¨μ- 첫λ²μ§Έ Falseλ₯Ό μ°Ύλ
&&μ°μ°μλ₯Ό μ¬μ©νμ¬μ vκ° nullκ°μ΄ μλκ³Symbol.iteratorνλ‘νΌν°κ° ν¨μμΈ κ²½μ°λ₯Ό μ°Ύλκ²
const array = [1, 2, 3];
// λ°°μ΄μ Array.prototypeμ Symbol.iterator λ©μλλ₯Ό μμλ°λ μ΄ν°λ¬λΈμ΄λ€.
console.log(Symbol.iterator in array); // true
// μ΄ν°λ¬λΈμΈ λ°°μ΄μ for...of λ¬ΈμΌλ‘ μν κ°λ₯νλ€.
for (const item of array) {
console.log(item); // 1 2 3
}
// μ΄ν°λ¬λΈμΈ λ°°μ΄μ μ€νλ λ λ¬Έλ²μ λμμΌλ‘ μ¬μ©ν μ μλ€.
console.log([...array]); // [1, 2, 3]
// μ΄ν°λ¬λΈμΈ λ°°μ΄μ λ°°μ΄ λμ€νΈλμ²λ§ ν λΉμ λμμΌλ‘ μ¬μ©ν μ μλ€.
const [a, ...rest] = array;
console.log(a, rest); // 1, [2, 3]Symbol.iteratorλ©μλλ₯Ό μ§μ ꡬννμ§ μκ±°λ μμλ°μ§ μμ μΌλ° κ°μ²΄λ μ΄ν°λ¬λΈ νλ‘ν μ½μ μ€μν μ΄ν°λ¬λΈμ΄ μλ β μΌλ°κ°μ²΄λfor..ofλ¬ΈμΌλ‘ μν X, μ€νλ λ λ¬Έλ²κ³Ό λ°°μ΄ λμ€νΈλμ²λ§ ν λΉμ λμ X
- μ΄ν°λ¬λΈμ
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 λ©μλλ μ΄ν°λ¬λΈμ κ° μμλ₯Ό μννκΈ° μν ν¬μΈν° μν
-
μ΄ν°λ¬λΈμ μμ°¨μ μΌλ‘ ν λ¨κ³ μ© μννλ©° μν κ²°κ³Όλ₯Ό λνλ΄λ μ΄ν°λ μ΄ν° 리μ νΈ κ°μ²΄(iterator result object)λ₯Ό λ°ν
// λ°°μ΄μ μ΄ν°λ¬λΈ νλ‘ν μ½μ μ€μν μ΄ν°λ¬λΈμ΄λ€.
const array = [1, 2, 3];
// Symbol.iterator λ©μλλ μ΄ν°λ μ΄ν°λ₯Ό λ°ννλ€. μ΄ν°λ μ΄ν°λ next λ©μλλ₯Ό κ°λλ€.
const iterator = array[Symbol.iterator]();
// next λ©μλλ₯Ό νΈμΆνλ©΄ μ΄ν°λ¬λΈμ μννλ©° μν κ²°κ³Όλ₯Ό λνλ΄λ μ΄ν°λ μ΄ν° 리μ νΈ κ°μ²΄λ₯Ό
// λ°ννλ€. μ΄ν°λ μ΄ν° 리μ νΈ κ°μ²΄λ valueμ done νλ‘νΌν°λ₯Ό κ°λ κ°μ²΄λ€.
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 }- νμ€ λΉνΈμΈ κ°μ²΄μ λΉνΈμΈ μ΄ν°λ¬λΈ
| λΉνΈμΈ μ΄ν°λ¬λΈ | Symbol.iterator λ©μλ |
|---|---|
| Array | Array.prototype[Symbol.iterator] |
| String | String.prototype[Symbol.iterator] |
| Map | Map.prototype[Symbol.iterator] |
| Set | Set.prototype[Symbol.iterator] |
| TypedArray | TypedArray.prototype[Symbol.iterator] |
| arguments | arguments[Symbol.iterator] |
| DOM 컬λ μ | NodeList.protytype[Symbol.iterator] |
| HTMLCollection.protytype[Symbol.iterator] |
for...ofλ¬Έμ μ΄λ¬ν°λΈμ μννλ©΄μ μ΄ν°λ¬λΈμ μμλ₯Ό λ³μμ ν λΉνλ€.for...inλ¬Έ μ νμκ³Ό λΉμ·νλ€
for λ³μμ μΈλ¬Έ of μ΄ν°λ¬λΈ){...}
for λ³μμ μΈλ¬Έ in κ°μ²΄ {...}
for...inλ¬Έμ κ°μ²΄λ₯Ό μννλ©° νλ‘νΌν° ν€κ° μ¬λ²μΈ νλ‘νΌν°λ μ΄κ±°νμ§ μλλ€.for...ofλ¬Έμ λ΄λΆμ μΌλ‘ μ΄ν°λ μ΄ν°μnextλ©μλλ₯Ό νΈμΆνμ¬ μ΄ν°λ¬λΈμ μννλ©°nextλ©μλκ° λ°νν μ΄ν°λ μ΄ν° 리μ νΈ κ°μ²΄μ value νλ‘νΌν° κ°μ λ³μμ ν λΉνλ€. 리μ νΈ κ°μ²΄μ done νλ‘νΌν° κ°μ΄ false μ΄λ©΄ μ΄ν°λ¬λΈμ μνλ₯Ό κ³μνκ³ μλλ©΄ μνλ₯Ό μ€λ¨νλ€.
// μ΄ν°λ¬λΈ
const iterable = [1, 2, 3];
// μ΄ν°λ¬λΈμ Symbol.iterator λ©μλλ₯Ό νΈμΆνμ¬ μ΄ν°λ μ΄ν°λ₯Ό μμ±νλ€.
const iterator = iterable[Symbol.iterator]();
for (;;) {
// μ΄ν°λ μ΄ν°μ next λ©μλλ₯Ό νΈμΆνμ¬ μ΄ν°λ¬λΈμ μννλ€. μ΄λ next λ©μλλ μ΄ν°λ μ΄ν° 리μ νΈ κ°μ²΄λ₯Ό λ°ννλ€.
const res = iterator.next();
// next λ©μλκ° λ°νν μ΄ν°λ μ΄ν° 리μ νΈ κ°μ²΄μ done νλ‘νΌν° κ°μ΄ trueμ΄λ©΄ μ΄ν°λ¬λΈμ μνλ₯Ό μ€λ¨νλ€.
if (res.done) break;
// μ΄ν°λ μ΄ν° 리μ νΈ κ°μ²΄μ value νλ‘νΌν° κ°μ item λ³μμ ν λΉνλ€.
const item = res.value;
console.log(item); // 1 2 3
}- μ μ¬ λ°°μ΄ κ°μ²΄ = λ§μΉ λ°°μ΄μ²λΌ μΈλ±μ€λ‘ νλ‘νΌν° κ°μ μ κ·Όν μ μκ³ length νλ‘νΌν°λ₯Ό κ°λ κ°μ²΄
- length νλ‘νΌν°λ₯Ό κ°κΈ° λλ¬Έμ forλ¬ΈμΌλ‘ μν κ°λ₯
- μΈλ±μ€λ₯Ό λνλ΄λ μ«μ νμμ λ¬Έμμ΄μ νλ‘νΌν° ν€λ‘ κ°μ§λ―λ‘ λ°°μ΄μ²λΌ μΈλ±μ€λ‘ νλ‘νΌν° κ°μ μ κ·Ό κ°λ₯
- μ΄ν°λ¬λΈμ΄ μλ μΌλ° κ°μ²΄ β
Symbol.iteratorλ©μλκ° μκΈ° λλ¬Έμfor...ofλ¬ΈμΌλ‘ μν X
// μ μ¬ λ°°μ΄ κ°μ²΄
const arrayLike = {
0: 1,
1: 2,
2: 3,
length: 3
};
// μ μ¬ λ°°μ΄ κ°μ²΄λ length νλ‘νΌν°λ₯Ό κ°κΈ° λλ¬Έμ for λ¬ΈμΌλ‘ μνν μ μλ€.
for (let i = 0; i < arrayLike.length; i++) {
// μ μ¬ λ°°μ΄ κ°μ²΄λ λ§μΉ λ°°μ΄μ²λΌ μΈλ±μ€λ‘ νλ‘νΌν° κ°μ μ κ·Όν μ μλ€.
console.log(arrayLike[i]); // 1 2 3
}- λ¨,
arguments,NodeList,HTMLCollectionμ μ μ¬ λ°°μ΄ κ°μ²΄μ΄λ©΄μ μ΄ν°λ¬λΈμ΄λ€. ES6λΆν° μ΄ν°λ¬λΈμ΄ λμ λλ©΄μ μμ 3κ°μ§κ° μ΄ν°λ¬λΈμ΄ λμλ€. - νμ§λ§ μ΄ν°λ¬λΈμ΄ λ μ΄νμλ 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
}μ΄ν°λ¬λΈμ λ°ννλ ν¨μ λ§λ€κΈ°
// νΌλ³΄λμΉ μμ΄μ ꡬνν μ¬μ©μ μ μ μ΄ν°λ¬λΈμ λ°ννλ ν¨μ. μμ΄μ μ΅λκ°μ μΈμλ‘ μ λ¬λ°λλ€.
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λ©μλλ₯Ό νΈμΆν΄μΌνλ€. Symbol.iteratorλ©μλλ thisλ₯Ό λ°ννλ―λ‘ next λ©μλλ₯Ό κ°λ μ΄ν°λ μ΄ν°λ₯Ό λ°ννλ€.
// μ΄ν°λ¬λΈμ΄λ©΄μ μ΄ν°λ μ΄ν°μΈ κ°μ²΄. μ΄ν°λ μ΄ν°λ₯Ό λ°ννλ Symbol.iterator λ©μλμ
// μ΄ν°λ μ΄μ
리μ νΈ κ°μ²΄λ₯Ό λ°ννλ next λ©μλλ₯Ό μμ νλ€.
{
[Symbol.iterator]() { return this; },
next() {
return { value: any, done: boolean };
}
}- 무ν μ΄ν°λ¬λΈ μμ±νλ ν¨μ
// 무ν μ΄ν°λ¬λΈμ μμ±νλ ν¨μ
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- μ΄ν°λ¬λΈμ μ§μ° νκ°λ₯Ό ν΅ν΄ λ°μ΄ν°λ₯Ό μμ±
- μ§μ° νκ° β νκ° κ²°κ³Όκ° νμν λκΉμ§ νκ°λ₯Ό λ¦μΆλ κΈ°λ²

