
μ΄ν°λ¬λΈ νλ‘ν μ½μ μν(λ°λ³΅) κ°λ₯ν κ°μ²΄λ₯Ό λνλ΄λ νλ‘ν μ½μ μλ―Ένλ€.
for...of λ°λ³΅λ¬Έ, ... μ κ° μ°μ°μ(Spread Operator), ꡬ쑰 λΆν΄ λ±κ³Ό ν¨κ» λμ ν μμλ€.
μλ ES5, ES6μμμ μνλ₯Ό λΉκ΅ν΄λ³΄μ
// index, length νλ‘νΌν°μ μμ‘΄
const arr = [1, 2, 3];
for (var i = 0; i < arr.length; i++) {
console.log(arr[i]) // 1 2 3
}
const str = 'abc';
for (var i = 0; i < str.length; i++) {
console.log(str[i]) // a b c
}
// ES6 μ΄ν --- μ μΈμ
for (const a of arr) {
console.log(a) // 1 2 3
}
for (const a of str) {
console.log(a) // a b c
}
array λΏλ§ μλλΌ κΈ°μ‘΄μ μΈλ±μ€ μ¬μ©μ΄ λΆκ°νλ set, mapκ³Ό κ°μ κ°μ²΄λ€μ λͺ¨λ for...of λ¬ΈμΌλ‘ μνν μ μλ€.
const set = new Set([1, 2, 3]);
for (const a of set) console.log(a) // 1 2 3
console.log(set[0]) // undefined
const map = new Map([['a', 1], ['b', 2], ['c', 3]]);
for (const a of map) console.log(a) // ["a", 1] ["b", 2] ["c", 3]
console.log(map[0]) // undefined
μ΄λ¬ν μ΄ν°λ¬λΈ νλ‘ν μ½μ ν΄λΉ κ°μ²΄κ° μ΄ν°λ¬λΈμ΄μ¬μΌλ§ κ°λ₯νλ€.
μ΄ν°λ¬λΈ(iterable) : μ΄ν°λ μ΄ν°(iterator)λ₯Ό 리ν΄νλ [Symbol.iterator]( )λΌλ ν€κ°μ λ©μλλ₯Ό κ°μ§ κ°μ²΄
ex. arr, set, map
μ΄ν°λ μ΄ν°(iterator) : { value, done }κ°μ²΄λ₯Ό 리ν΄νλ next()λ©μλλ₯Ό κ°μ§ κ°μ²΄
console.dir(arr);
/*
> Array(3)
> __proto__ : Array(0)
...
> Symbol(Symbol.iterator): Ζ values()
...
*/
μμμ μ μν arrμ΄ λ΄λΆμμ Symbol(Symbol.iterator): Ζ values()λ₯Ό νμΈν¨μΌλ‘ λ€μκ³Ό κ°μ μ¬μ€μ μ μ μλ€.
μ κ°μ°μ°μ μμ iterator protocolμ λ°λ₯΄κ³ μλ€
const a = [1, 2];
console.log([...a, ...[3, 4]]); // [ 1, 2, 3, 4 ]
console.log([...arr, ...set, ...map]); // [ 1, 2, 3, 1, 2, 3, [ 'a', 1 ], [ 'b', 2 ], [ 'c', 3 ] ]
a[Symbol.iterator] = null;
console.log([...a, ...[3, 4]]); // TypeError: a is not iterable
μ΄ν°λ¬λΈ νλ‘ν μ½μ λ°λΌ μν λμμ μ¬μ©μκ° μμλ‘ μ μν μ μλ€. μ΄λ μ΄ν°λ¬λΈμ΄ λ€μνκ² νμ©λ μ μμμ λ»νλ€.
const iterable = {
[Symbol.iterator]() {
let i = 3;
return {
next() {
return i === 0 ? { done: true } : { value: i--, done: false }
},
[Symbol.iterator]() { return this; }
}
}
}
let iterator = iterable[Symbol.iterator]();
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { done: true }
for (const a of iterable) console.log(a) // 3 2 1
μ λλ μ΄ν°μ μ€ν κ²°κ³ΌμΈ μ λλ μ΄ν° κ°μ²΄λ μ΄ν°λ μ΄ν° κ°μ²΄μ΄λ€.
λν [Symbol.iterator]()λ₯Ό κ°μ§λ μ΄ν°λ¬λΈμ΄κΈ°λ νλ€.
function *generator() {
yield 1;
if (false) yield 2;
yield 3;
return 100;
}
let iter = generator();
console.log(iter[Symbol.iterator]() == iter) // true
console.log(iter.next()); // {value: 1, done: false}
console.log(iter.next()); // {value: 3, done: false}
console.log(iter.next()); // {value: 100, done: true}
console.log(iter.next()); // {value: undefined, done: true}
for (const a of generator()) console.log(a) // 1 3
μ λλ μ΄ν° κ°μ²΄λ μ΄ν°λ μ΄ν°μ΄μ μ΄ν°λ¬λΈμ΄κΈ° λλ¬Έμ μμ μνκ° κ°λ₯νλ€. λν μ λλ μ΄ν°μλ λ§μ§λ§μ λ¦¬ν΄ κ°μ λ§λ€ μ μλ€. νμ§λ§ done λν tureκ° λκΈ° λλ¬Έμ μνμ λμμ΄ λμ§ μλλ€.
μ΄ν°λ¬λΈκ³Ό μ λ€λ μ΄ν°... λλΆμ λ€μν λ°μ΄ν° νμ λ€μ μννκ³ κ°κ³΅νλ κ²μ λ§€μ° νΈλ¦¬νκ² ν΄μ€ κ² κ°λ€!bb μ 체μ μΈ μ»¨μ μ μ΄ν΄κ° λλ, μμ§κΉμ§ κ° λ¨μ΄μ κ°λ μ΄ μλ²½ν μ 립λμ§ μμκΈ° λλ¬Έμ λ€μνκ² μμ±ν΄λ³΄κ³ μ²μ²ν μ΅νλ©° μ΅λμ ν κ³νμ΄λ€.