π Intro
Iterate λ 'λ°λ³΅νλ€' λ μ¬μ μ μλ―Έλ₯Ό κ°μ§κ³ μλ μ©μ΄λ‘, νλ‘κ·Έλλ°μμλ μ£Όλ‘ 'λ°λ³΅ κ°λ₯ν κ°μ²΄' λ₯Ό μλ―Ένλ€. μλ°μ€ν¬λ¦½νΈμλ§ μ‘΄μ¬νλ κ°λ μ μλμ§λ§, μλ°μ€ν¬λ¦½νΈμ μ΄ν°λ¬λΈ κ°λ μ νμ΅νλ©΄ λ€λ₯Έ νλ‘κ·Έλλ° μ©μ΄μλ μ½κ² μ μ©ν μ μλ€.
β¨ ES6 μ μΆκ°λ Iterable
ECMAScript λ μλ°μ€ν¬λ¦½νΈλ₯Ό νμ€ννκ³ ν λλ₯Ό ꡬμ±νκΈ° μν΄ λ§λ€μ΄μ§ νμ€νλ μ€ν¬λ¦½νΈ νλ‘κ·Έλλ° μΈμ΄μ΄λ©°, ES6μ 6λ²μ§Έ ECMAScript λ²μ μ μλ―Ένλ€. ES6 μ 2015λ μ μ μ λμλλ°, μ΄μ κΉμ§ λ¬Έμ κ° λμλ λ§μ λΆλΆλ€μ΄ ν΄κ²°λκ³ κΈ°λ₯μ΄ λκ±° μΆκ°λμ΄ μλ°μ€ν¬λ¦½νΈμ κ°λ μ±κ³Ό μ μ§λ³΄μμ±μ ν₯μνλ€.
ES6μλ κΈ°μ‘΄μ μμλ Scope, parameter handling, ꡬ쑰λΆν΄ ν λΉ λ± JS κ°λ°μλ€μ΄ νν μ¬μ©νλ μ¬λ¬ κ°λ λ€μ΄ λμ λμλ€. μ΄ λ ν¨κ» λμ λ κ²μ΄ λ°λ‘ Iterable κ³Ό Iterator λ₯Ό κ΄λͺ©νλ Iteration Protocol μ΄λ€.
βES6 μ΄μ μλ iteration protocol μμ΄λ λ°°μ΄, λ¬Έμμ΄ λ±μ for, while λ¬Έκ³Ό κ°μ λ°λ³΅λ¬ΈμΌλ‘ μνν μ μμλ€. ES6μ λ€μ΄μλ©° μ΄λ¬ν λ°λ³΅ν κ°μ²΄λ€μ νλ‘ν μ½μ΄ ν΅μΌλκ³ , μ¬λ¬ λ©μλμ κ³΅ν΅ λμμ΄ λ μ μλλ‘ ν κ²μ΄λ€.
β¨ Iteration Protocol
Iteration protocol μμλ Iterable protocol κ³Ό Iterator protocol μ΄ μ‘΄μ¬νλ€.
Symbol.iterator λ₯Ό νλ‘νΌν° ν€λ‘ μ¬μ©ν λ©μλλ₯Ό μ§μ ꡬννκ±°λ, νλ‘ν νμ 체μΈμ ν΅ν΄ μμνμ¬ νΈμΆν¨μΌλ‘μ¨ iteratorλ₯Ό λ°ννλ κ·μ½μ΄ π‘Iterable protocolμ΄λ€. μ΄ λ, iterable protocol μ μ€μν κ°μ²΄λ iterable μ΄λΌκ³ νλ€. (for.. of, spread, rest λ¬Έλ² λμμ΄ λ¨) Iterable μ Symbol.iterator λ©μλλ₯Ό νΈμΆνλ©΄ iterator λ₯Ό λ°ννλλ°, μ΄ iterator λ π‘Iterator protocol λ₯Ό μ€μνλ€ (next method, value property, done property μμ ). Iterator λ iterable μ μμλ₯Ό νμνκΈ° μν ν¬μΈν° μν μ νλ€.
λ§μ΄ μ΄λ ΅κ³ μ€λ³΅λλ λ΄μ©μ΄ λ§μ λ³΄μΌ κ²μ΄λ€. λ΄μ©μ μ°¨λ‘λ‘ μ΄ν΄λ³΄λ©° μ΄λ»κ² λ€λ₯Έ κ²μΈμ§ μ΄ν΄λ³΄μ.
β νμ§λ§ κ·Έ μ μ μ°μ Symbol.iterator μ λν μ΄ν΄κ° νμνλ€. μλ°μ€ν¬λ¦½νΈμλ λΉνΈμΈ Symbol ν¨μκ° μλ€. μ΄ Symbol ν¨μ μμλ λΉνΈμΈ μ¬λ²λ€μ΄ νλ‘νΌν°λ‘ ν λΉλμ΄ μμΌλ©°, μ΄λ€μ Well-known Symbol μ΄λΌκ³ λΆλ₯Έλ€. μ΄ μ€ νλμΈ Symbol.iterator μμ λΉνΈμΈ μ¬λ²μ΄λ€.
Iterable protocolμ λ°λ₯΄λ κ°μ²΄ (Iterable) λ λ€μκ³Ό κ°μ νΉμ§μ κ°λλ€.
1. Symbol.iterator λ₯Ό νλ‘νΌν° ν€λ‘ μ¬μ©ν λ©μλλ₯Ό ꡬννλ€
2. Symbol.iterator λ₯Ό νλ‘ν νμ 체μΈμ ν΅ν΄ μμλ°λλ€
κ·Έλ¦¬κ³ Iterator protocol μ λ°λ₯΄λ κ°μ²΄ (iterator) λ λ€μκ³Ό κ°μ νΉμ§μ κ°λλ€.
3. next λ©μλ μμ
4. next λ©μλμ κ²°κ³Ό κ°μ²΄μ done, value νλ‘νΌν°λ₯Ό μμ
λ€μ μμκ° μμ λ΄μ©μ λͺ μΎνκ² μ 리νλ€.
const test = {
[Symbol.iterator]() {
let cur = 1;
const max = 5;
return {
next() {
return {value: cur++, done: cur > max + 1}
}
}
}
}
μμ test κ°μ²΄λ Symbol.iterator λ₯Ό νλ‘νΌν° ν€λ‘ μ¬μ©νμ¬, λ©μλλ₯Ό ꡬννκ³ μκΈ° λλ¬Έμ (1λ² νΉμ§) iterable protocol μ μ€μνλ€. λ°λΌμ test κ°μ²΄λ 곧 iterable μ΄λ€.
λν, test μμ ꡬνλ Symbol.iterator λ©μλλ₯Ό μ€ννλ©΄ iterator κ° λ°νμ΄ λλλ°, μ΄ iterator λ next λ©μλλ₯Ό κ°μ§λ©° (3λ² νΉμ§), next() μ μ€ν κ²°κ³Όμ value μ done νλ‘νΌν°λ₯Ό κ°λλ€ (4λ² νΉμ§).
for (let num of test){
console.log(num) // 1 2 3 4 5
}
let it = test[Symbol.iterator]();
it.next() // {value: 1, done: false}
it.next() // {value: 2, done: false}
it.next() // {value: 3, done: false}
it.next() // {value: 4, done: false}
it.next() // {value: 5, done: true}
μμ μμμ λμ¨ next λ©μλλ iterable μ κ° μμλ₯Ό μννκΈ° μν ν¬μΈν° μν μ νλ€. κ·Έλ¦¬κ³ μνμ κ²°κ³Όλ‘ λμ€λ κ°μ²΄λ₯Ό iterator result object λΌκ³ μΉνλ€.
π‘ μ 리νμλ©΄, iterator λ₯Ό λ°ννλ λ©μλλ₯Ό κ°λ κ°μ²΄λ₯Ό iterable μ΄λΌκ³ νλ©°, μ΄λ¬ν iterable μ iteration protocol μ μ€μνλ€.
μ°λ¦¬κ° νν μλ Array, String, Map, Set λ±μ κ°μ²΄λ€μ λͺ¨λ λΉνΈμΈ (λ΄μ₯λ) iterable μ΄λ©°, μμ μμμ²λΌ μλ‘κ² λ§λ κ°μ²΄λ€λ λͺ¨λ iterable μ΄λ€. μ΄λ ν κ°μ²΄κ° iterable μΈμ§ μ¬λΆλ₯Ό νμΈνκ³ μ νλ€λ©΄ λ€μκ³Ό κ°μ λ°©λ²μ μ¬μ©νλ©΄ λλ€. (λ€μ μμμμλ Array.prototype μ Symbol.iterator λ©μλλ₯Ό μμλ°μ λ°°μ΄μ μ¬μ©νλ€)
// λ°©λ² 1 : κ°μ²΄ λ΄λΆμ Symbol.iterator λ₯Ό ν€λ‘ κ°λ λ©μλ μλμ§ νμΈ
const iter = [];
iter[Symbol.iterator] // ƒ values() { [native code] }
// λ°©λ² 2 : κ°μ²΄μ key κ° μ§μ νμΈ
Symbol.iterator in []; // true
β¨ Iterable νΉμ§
μ κΉ μΈκΈνμ§λ§ iterable μ κ°μ₯ ν° νΉμ§μ for..of λ¬ΈμΌλ‘ μ‘°ν, spread λ¬Έλ², λ°°μ΄ destructuring λ¬Έλ²μ λμμ΄ λλ€λ μ μ΄λ€.
1. for...of λ¬Έ μ‘°ν
const arr = [ 1, 2, 3 ];
for (let a of arr) {
console.log(a)
};
// 1
// 2
// 3
for ...of λ¬Έμ iterable μ μ‘°ννλ κ²μ΄λ©°, for ...in λ¬Έμ κ°μ²΄λ₯Ό μ‘°ννλ νμμ΄λ€. for .. of λ¬Έμ iterator μ next λ¬Έμ νΈμΆνλ©°, κ·Έ κ²°κ³ΌμΈ iterator result object μ value λ₯Ό for ...of λ¬Έμ λ³μμ ν λΉνλ€. (μμ κ²½μ°μλ a) iterator result object μ done κ°μ΄ true κ° λμ€λ μκ°, μνλ₯Ό μ€λ¨νλ€.
βμ μ¬ λ°°μ΄ κ°μ²΄λ iterator κ° μλκΈ° λλ¬Έμ for...of μ‘°νκ° λΆκ°λ₯νλ€. νμ§λ§ μμΈκ° μ‘΄μ¬νλλ°, arguments, NodeList , HTMLCollection μ μ μ¬ λ°°μ΄ κ°μ²΄μ΄λ©΄μλ iterable μ΄λ€.
2. spread λ¬Έλ²
console.log(...arr) // 1, 2, 3
β λ¬Έμμ΄μ iterable μ΄κΈ° λλ¬Έμ λ°°μ΄ destructuring μ΄ κ°λ₯νμ§λ§, κ°μ²΄λ μλκΈ° λλ¬Έμ λΆκ°λ₯νλ€.
let ha = 'haha';
const [b,rest] = ha;
console.log(b) // 'h'
let ha2 = {a:1, b:2};
const [a, b] = ha2; // TypeError
3. λ°°μ΄ destructuring λ¬Έλ²
const [a, ...rest] = arr;
console.log(a) // 1
console.log(rest) // [2, 3]
β ν·κ°λ¦¬λ©΄ μλλ κ²μ, iterable μ΄ μλ κ°μ²΄({})λΌλ κ°μ²΄ 리ν°λ΄ λ΄μμμ spread λ destructuring μ κ°λ₯νλ€.
β¨ Iteration Protocol μ νμμ±
Iteration Protocol μ΄ κ·μ λκ³ μ¬λ¬ μλ£κ΅¬μ‘°κ° iterator μ νμμ μ·¨νλ©΄μ, λ€μν λ°μ΄ν° 곡κΈμ (μλ£κ΅¬μ‘°) κ° νλμ μν λ°©μμ κ°λλ‘ κ·μ λμλ€. μ΄λ λ°μ΄ν° μ·¨λκ³Ό μ¬μ©μ ν¨μ¨μ±μ κ΅μ₯ν λμ¬μ£Όλ λ°©μμ΄λ€.
πμ€μ μ¬μ©λ‘
- set λ±μ μλ£κ΅¬μ‘°μ μ μ©νκΈ° λ§€μ° κ°νΈν¨ (for.. in λΆκ°λ₯)
- κ²°κ³Όκ°μ νκ³λ₯Ό λμ§ μκ³ κ°μ²΄λ₯Ό μ¬μ©νκ³ μ νλ κ²½μ°
- μ§μ° νκ° (lazy evaluation) μ΄ νμν κ²½μ° : λ°μ΄ν°κ° νμν μμ μ΄μ κΉμ§λ 미리 λ°μ΄ν°λ₯Ό μμ±νμ§ μλ€κ° νμν μμ μ΄ λλ©΄ λ°μ΄ν°λ₯Ό μμ±νλ κΈ°λ²
β¨ μ°Έκ³ μλ£
- λͺ¨λ μλ°μ€ν¬λ¦½νΈ Deep Dive (μν€λΆμ€)
'π» DEV > Javascript & NodeJS' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[JavaScript] ν΄λμ€ (Class) (0) | 2021.12.12 |
---|---|
[Javascript] Generator (μ λ€λ μ΄ν°) (0) | 2021.10.26 |
[Javascript] ν΄λ‘μ (Closure) (0) | 2021.10.06 |
[Javascript] μ€ν 컨ν μ€νΈ (Execution Context) μ μμ€μ½λ (0) | 2021.09.28 |
[NodeJS] Node μ this λ? (+ νμ΄ν ν¨μμ this) (2) | 2021.09.10 |
λκΈ